summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jerry2/WHATSNEW.txt1588
-rw-r--r--jerry2/source/include/mangle.h14
-rwxr-xr-xjerry2/source/include/proto.h5092
-rwxr-xr-xjerry2/source/include/version.h1
-rw-r--r--jerry2/source/smbd/filename.c506
-rw-r--r--jerry2/source/smbd/mangle.c123
-rw-r--r--jerry2/source/smbd/mangle_hash.c880
-rw-r--r--jerry2/source/smbd/mangle_hash2.c661
-rw-r--r--jerry2/source/smbd/reply.c5173
9 files changed, 14038 insertions, 0 deletions
diff --git a/jerry2/WHATSNEW.txt b/jerry2/WHATSNEW.txt
new file mode 100644
index 00000000000..d076c510762
--- /dev/null
+++ b/jerry2/WHATSNEW.txt
@@ -0,0 +1,1588 @@
+ ==============================
+ Release Notes for Samba 2.2.10
+ July 22, 2004
+ ==============================
+
+
+######################## SECURITY RELEASE ########################
+
+Summary: Potential Buffer Overrun in Samba 2.2.x
+CVE ID: CAN-2004-0686
+ (http://cve.mitre.org/)
+
+This is the latest stable release of the Samba 2.2 code base.
+There are no further Samba 2.2.x releases planned at this time.
+
+-------------
+CAN-2004-0686
+-------------
+
+Affected Versions: Samba 2.2.0 through 2.2.9
+
+A buffer overrun has been located in the code used to support
+the 'mangling method = hash' smb.conf option. Affected Samba
+2.2 installations can avoid this possible security bug by using
+the hash2 mangling method. Server installations requiring
+the hash mangling method are encouraged to upgrade to Samba v2.2.10
+or v3.0.5.
+
+
+Older releases notes for 2.2.x distributions follow
+
+ ------------------------------------------------------
+
+ =============================
+ Release Notes for Samba 2.2.9
+ May 8, 2004
+ =============================
+
+This is the latest stable release of the Samba 2.2 code base.
+This is a maintenance release of Samba 2.2.8a to address the
+problem with user password changes after applying the Microsoft
+hotfix described in KB282741 to Windows NT 4.0/200x/XP clients.
+No other changes have been applied since Samba 2.2.8a.
+
+There are no further Samba 2.2.x releases planned at this time.
+
+
+ ------------------------------------------------------
+
+ ===========================================
+ What's new in Samba 2.2.8a - 7th April 2003
+ ===========================================
+
+ ****************************************
+ * IMPORTANT: Security bugfix for Samba *
+ ****************************************
+
+Summary
+-------
+
+Digital Defense, Inc. has alerted the Samba Team to a serious
+vulnerability in all stable versions of Samba currently shipping.
+The Common Vulnerabilities and Exposures (CVE) project has assigned
+the ID CAN-2003-0201 to this defect.
+
+This vulnerability, if exploited correctly, leads to an anonymous
+user gaining root access on a Samba serving system. All versions
+of Samba up to and including Samba 2.2.8 are vulnerable. An active
+exploit of the bug has been reported in the wild. Alpha versions of
+Samba 3.0 and above are *NOT* vulnerable.
+
+
+Credit
+------
+
+The Samba Team would like to thank Erik Parker and the team at
+Digital Defense, Inc. for their efforts spent in the responsible
+and timely reporting of this bug.
+
+
+Patch Availability
+------------------
+
+The Samba 2.2.8a release contains only updates to address this
+security issue. A roll-up patch for release 2.2.7a and 2.0.10
+addressing both CAN-2003-0201 and CAN-2003-0085 can be obtained
+from http://www.samba.org/samba/ftp/patches/security/.
+
+
+ ========================================
+
+
+Older releases notes for 2.2.x distributions follow
+
+-----------------------------------------------------------------
+The release notes for 2.2.8 follow:
+
+ ****************************************
+ * IMPORTANT: Security bugfix for Samba *
+ ****************************************
+
+Summary
+-------
+
+The SuSE security audit team, in particular Sebastian Krahmer
+<krahmer@suse.de>, has found an flaw in the Samba main smbd code which
+could allow an external attacker to remotely and anonymously gain
+Super User (root) privileges on a server running a Samba server.
+
+This flaw exists in previous versions of Samba from 2.0.x to 2.2.7a
+inclusive. This is serious problem and all sites should either
+upgrade to Samba 2.2.8 immediately or prohibit access to TCP ports 139
+and 445. Advice on how to protect an unpatched Samba server created by
+Andrew Tridgell, the leader of the Samba Team, is given at the end of
+this section.
+
+The SMB/CIFS protocol implemented by Samba is vulnerable to many
+attacks, even without specific security holes. The TCP ports 139 and
+the new port 445 (used by Win2k and the Samba 3.0 alpha code in
+particular) should never be exposed to untrusted networks.
+
+Description
+-----------
+
+A buffer overrun condition exists in the SMB/CIFS packet fragment
+re-assembly code in smbd which would allow an attacker to cause smbd
+to overwrite arbitrary areas of memory in its own process address
+space. This could allow a skilled attacker to inject binary specific
+exploit code into smbd.
+
+This version of Samba adds explicit overrun and overflow checks on
+fragment re-assembly of SMB/CIFS packets to ensure that only valid
+re-assembly is performed by smbd.
+
+In addition, the same checks have been added to the re-assembly
+functions in the client code, making it safe for use in other
+services.
+
+Credit
+------
+
+This security flaw was discovered and reported to the Samba Team by
+Sebastian Krahmer <krahmer@suse.de> of the SuSE Security Audit Team.
+The fix was prepared by Jeremy Allison and reviewed by engineers from
+the Samba Team, SuSE, HP, SGI, Apple, and the Linux vendor engineers
+on the Linux Vendor security mailing list.
+
+The Samba Team would like to thank SuSE and Sebastian Krahmer for
+their excellent auditing work and for drawing attention to this flaw.
+
+Patch Availability
+-----------------
+
+As this is a security issue, patches for this flaw specific to earlier
+versions of Samba will be and posted on the samba-technical@samba.org
+mailing list as requested.
+
+
+************************************
+Protecting an unpatched Samba server
+************************************
+
+ Samba Team, March 2003
+
+ This is a note on how to provide your Samba server some
+ protection against the recently discovered remote security
+ hole if you are unable to upgrade to the fixed version
+ immediately. Even if you do upgrade you might like to think
+ about the suggestions in this note to provide you with
+ additional levels of protection.
+
+
+ Using host based protection
+ ---------------------------
+
+ In many installations of Samba the greatest threat comes for
+ outside your immediate network. By default Samba will accept
+ connections from any host, which means that if you run an
+ insecure version of Samba on a host that is directly
+ connected to the Internet you can be especially vulnerable.
+
+ One of the simplest fixes in this case is to use the 'hosts
+ allow' and 'hosts deny' options in the Samba smb.conf
+ configuration file to only allow access to your server from a
+ specific range of hosts. An example might be:
+
+ hosts allow = 127.0.0.1 192.168.2.0/24 192.168.3.0/24
+ hosts deny = 0.0.0.0/0
+
+ The above will only allow SMB connections from 'localhost'
+ (your own computer) and from the two private networks
+ 192.168.2 and 192.168.3. All other connections will be
+ refused connections as soon as the client sends its first
+ packet. The refusal will be marked as a 'not listening on
+ called name' error.
+
+
+ Using interface protection
+ --------------------------
+
+ By default Samba will accept connections on any network
+ interface that it finds on your system. That means if you
+ have a ISDN line or a PPP connection to the Internet then
+ Samba will accept connections on those links. This may not be
+ what you want.
+
+ You can change this behavior using options like the
+ following:
+
+ interfaces = eth* lo
+ bind interfaces only = yes
+
+ that tells Samba to only listen for connections on interfaces
+ with a name starting with 'eth' such as eth0, eth1, plus on
+ the loopback interface called 'lo'. The name you will need to
+ use depends on what OS you are using, in the above I used the
+ common name for ethernet adapters on Linux.
+
+ If you use the above and someone tries to make a SMB
+ connection to your host over a PPP interface called 'ppp0'
+ then they will get a TCP connection refused reply. In that
+ case no Samba code is run at all as the operating system has
+ been told not to pass connections from that interface to any
+ process.
+
+
+ Using a firewall
+ ----------------
+
+ Many people use a firewall to deny access to services that
+ they don't want exposed outside their network. This can be a
+ very good idea, although I would recommend using it in
+ conjunction with the above methods so that you are protected
+ even if your firewall is not active for some reason.
+
+ If you are setting up a firewall then you need to know what
+ TCP and UDP ports to allow and block. Samba uses the
+ following:
+
+ UDP/137 - used by nmbd
+ UDP/138 - used by nmbd
+ TCP/139 - used by smbd
+ TCP/445 - used by smbd
+
+ The last one is important as many older firewall setups may
+ not be aware of it, given that this port was only added to
+ the protocol in recent years.
+
+
+ Using a IPC$ share deny
+ -----------------------
+
+ If the above methods are not suitable, then you could also
+ place a more specific deny on the IPC$ share that is used in
+ the recently discovered security hole. This allows you to
+ offer access to other shares while denying access to IPC$
+ from potentially untrustworthy hosts.
+
+ To do that you could use:
+
+ [ipc$]
+ hosts allow = 192.168.115.0/24 127.0.0.1
+ hosts deny = 0.0.0.0/0
+
+ this would tell Samba that IPC$ connections are not allowed
+ from anywhere but the two listed places (localhost and a
+ local subnet). Connections to other shares would still be
+ allowed. As the IPC$ share is the only share that is always
+ accessible anonymously this provides some level of protection
+ against attackers that do not know a username/password for
+ your host.
+
+ If you use this method then clients will be given a 'access
+ denied' reply when they try to access the IPC$ share. That
+ means that those clients will not be able to browse shares,
+ and may also be unable to access some other resources.
+
+ I don't recommend this method unless you cannot use one of
+ the other methods listed above for some reason.
+
+
+ Upgrading Samba
+ ---------------
+
+ Of course the best solution is to upgrade Samba to a version
+ where the bug has been fixed. If you wish to also use one of
+ the additional measures above then that would certainly be a
+ good idea.
+
+ Please check regularly on http://www.samba.org/ for updates
+ and important announcements.
+
+
+ ****************************************
+ ****************************************
+
+
+Changes since 2.2.7a
+---------------------
+
+New Parameters
+
+ * acl compatibility
+
+Additional Changes:
+ See the cvs log for SAMBA_2_2 for more details
+
+1) smbumount lazy patch from Mandrake
+2) Check for too many processes *before* the fork.
+3) make sure we don't run over the end of 'name' in unix_convert()
+4) set umask to 0 before creating socket directory.
+5) Fix the LARGE_SMB_OFF_T problems and allow smbd to do the right
+ thing in interactive mode when a log file dir is also specified.
+6) Fix delete on close semantics to match W2K.
+7) Correctly return access denied on share mode deny when we can't
+ open the file.
+8) Always use safe_strcpy not pstrcpy for malloc()'d strings
+9) Fixes for HP-UX only having limited POSIX lock range
+10) Added uid/gid caching code. Reduces load on winbindd.
+11) Removed extra copy of server name in the printername field (it was
+ mangling the the name to be \\server\\\server\printer
+12) Fix dumb perror used without errno being set.
+13) Do retries correctly if the connection to the DC has failed.
+14) Correctly check for inet_addr fail.
+15) Ensure we use getgrnam() unless BROKEN_GETGRNAM is defined.
+16) Fix for missing if (setting_acls) on default perms.
+17) Fix to cache the sidtype
+18) fix printer settings on Solaris (big-endian) print servers.
+ ASCII -> UNICODE conversion bug.
+19) Small fix check correct error return.
+20) Ensure space_avail is unsigned.
+21) patch to check for a valid [f]chmod_acl function pointer
+ before calling it. Fixes seg fault in audit VFS module
+22) When checking is_locked() new WRITE locks conflict with existing
+ READ locks even if the context is the same.
+23) Merge off-by-one crash fixes from HEAD
+24) Move off-by-one buggy malloc()/safe_strcpy() combination to
+ strdup() instead.
+25) Merge from HEAD. Use pstrcpy not safe_strcpy.
+26) Fix to allow blocking lock notification to be done rapidly (no wait
+ for smb -> smb lock release). Adds new PENDING_LOCK type to lockdb
+ (does not interfere with existing locks).
+27) Doxygen cleanups for code documentation
+28) limit the unix domain sockets used by winbindd by adding a
+ "last_access" field to winbindd connections, and will close
+ the oldest idle connection once the number of open connections goes
+ over WINBINDD_MAX_SIMULTANEOUS_CLIENTS (defined in local.h as 200
+ currently)
+29) Fix a couple of string handling errors in smbd/dir.c that would
+ cause smbd to crash
+30) Fix seg fault in smbpasswd when specifying the new password
+ as a command line argument
+31) Correct 64-but file sizes issues with smbtar and smbclient
+32) Add batch mode option to pdbedit
+33) Add protection in nmbd against malformed reply packets
+34) Fix bug with sendfile profiling support in smbstatus output
+35) Correct bug in "hide unreadable" smb.conf parameter that
+ resulted in incorrect directory listings
+36) Fix bug in group enumeration in winbindd
+37) Correct build issues with libsmbclient on Solaris
+38) Fix memory leak and bad pointer dereference in password
+ changing code in smbd
+39) Fix for changing attributes on a file truncate
+40) Ensure smbd process count never gets to -1 if limiting number
+ of processes
+41) Ensure we return disk full by default on short writes
+42) Don't delete jobs submitted after the lpq time
+43) Fix reference count bug where smbds would not terminate
+ with no open resources
+44) Performance fix when using quota support on HP-UX
+45) Fixes for --with-ldapsam
+ * Default to port 389 when "ldap ssl != on"
+ * add support for rebinding to the master directory server
+ for password changes when "ldap server" points to a read-only
+ slave
+46) Add -W and -X command line flags to smbpasswd for extracting and
+ setting the machine/domain SID in secrets.tdb. See the
+ smbpasswd(8) man page for details.
+47) Added (c) Luke Howard to winbind_nss_solaris.c for coded
+ obtained from PADL's nss_ldap library.
+48) Fix bug in samr_dispinfo query in winbindd
+49) Fix segfault in NTLMSSP password changing code for
+ guest connections
+50) Correct pstring/fstring mismatches
+51) Send level II oplock break requests synchronously to prevent
+ condition where one smbd would continually lock a share entry
+ in locking.tdb
+52) Miscellaneous cleanups for tdb error conditions and appending
+ data in a record
+53) Implement correct open file truncate semantics with DOS
+ attributes
+54) Enforce wide links = no on files as well as directories
+55) Include shared library checks for Stratus VOS
+56) Include support for CUPS printer classes and logging the remote
+ client name
+57) Include "WinXP" (Windows XP) and "Win2K3" (Windows .NET) values
+ for %a
+58) Increase the max PDU size to deal with some troublesome printer
+ drivers and Windows NT 4.0 clients
+59) increment the process counter immediately after the fork
+ (not just when we receive the first smb packet)
+60) Ensure rename sets errno correctly
+61) Unify ACL code (back-port from 3.0)
+62) Fix some further issues around off_t and large offsets
+
+
+Changes since 2.2.7
+--------------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) Fix for smbclient reporting negative file sizes on dir command
+ and negative statistics being reported when using put or get
+ on large files.
+2) Fix bug in determination of allocation size
+3) Fix 64bit size problems which prevented copying of files larger
+ than 2 GBytes.
+4) Fix for xcopy /s problem with old DOS clients not sending correct
+ attributes on subsequent SMBsearch calls.
+5) Fix bug in call to standard_sub_advanced giving a 0 length. This
+ fixes the string overflow in string_sub errors.
+6) Correctly handle querygroup rpcclient command
+7) fix broken incremental tar in smbtar command
+
+
+The release notes for 2.2.7 follow :
+
+IMPORTANT: Security bugfix for Samba
+------------------------------------
+
+Summary
+-------
+
+A security hole has been discovered in versions 2.2.2 through 2.2.6
+of Samba that could potentially allow an attacker to gain root access
+on the target machine. The word "potentially" is used because there
+is no known exploit of this bug, and the Samba Team has not been able to
+craft one ourselves. However, the seriousness of the problem warrants
+this immediate 2.2.7 release.
+
+In addition to addressing this security issue, Samba 2.2.7 also includes
+thirteen unrelated improvements. These improvements result from our
+process of continuous quality assurance and code review, and are part of
+the Samba team's commitment to excellence.
+
+Details
+-------
+
+There was a bug in the length checking for encrypted password change
+requests from clients. A client could potentially send an encrypted
+password, which, when decrypted with the old hashed password could be
+used as a buffer overrun attack on the stack of smbd. The attach would
+have to be crafted such that converting a DOS codepage string to little
+endian UCS2 unicode would translate into an executable block of code.
+
+All versions of Samba between 2.2.2 to 2.2.6 inclusive are vulnerable
+to this problem. This version of Samba 2.2.7 contains a fix for this
+problem.
+
+Earlier versions of Samba are not vulnerable.
+
+There is no known exploit or exploit code for this vulnerability,
+it was discovered by a code audit by Debian Samba maintainers.
+
+Credit
+------
+
+Thanks to Steve Langasek <vorlon@debian.org> and Eloy Paris
+<peloy@debian.org> for bringing this vulnerability to our notice.
+
+Patch for Samba versions 2.2.2 to 2.2.6
+---------------------------------------
+
+The following patch applies cleanly to the above Samba versions
+and will fix the vulnerability for sites that do not wish to upgrade
+to 2.2.7 at this time.
+
+
+-------------------------------cut here---------------------------------
+--- libsmb/smbencrypt.c.orig Tue Nov 19 17:21:57 2002
++++ libsmb/smbencrypt.c Tue Nov 19 17:22:12 2002
+@@ -63,7 +63,7 @@
+ if(len > 128)
+ len = 128;
+ /* Password must be converted to NT unicode - null terminated. */
+- dos_struni2((char *)wpwd, (const char *)passwd, 256);
++ dos_struni2((char *)wpwd, (const char *)passwd, len);
+ /* Calculate length in bytes */
+ len = strlen_w((const smb_ucs2_t *)wpwd) * sizeof(int16);
+-------------------------------cut here---------------------------------
+
+
+
+Changes since 2.2.6
+--------------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) ensure we send the notify message in the same way it is expected
+ to be received by srv_spoolss_receive_message().
+2) attribute matching on truncate only matters when opening truncate
+ with current SYSTEM|HIDDEN -> NONE. It's fine to truncate on open
+ with current NONE -> SYSTEM | HIDDEN.
+3) Fix bug in rpcclient's deldriver command
+4) Don't set global_machine_password_needs_changing if
+ lp_machine_password_timeout() is set to zero
+5) don't parse the BUFFER5 if the buffer length is zero
+6) fix core dump if pdbedit is run as non-root or smbpasswd file does
+ not exist
+7) Ensure can_delete() returns correct error code
+8) correctly return NT_STATUS_DELETE_PENDING from open code
+9) fix bug that assumed dos_unistr2 length was in ucs2 units, not
+ bytes
+10) check the long_archi name is not null when deleting a printer
+ driver. fixes core dump in smbd when using rpcclient's deldriver
+11) fix fd leak with kernel change notify on Linux 2.4 kernels
+12) must add one to the extra_data size to transfer the 0 string
+ terminator. This was causing "wbinfo --sequence" to access past
+ the end of malloced memory
+13) fix for large systems allowing more than 65536 files open in
+ NTcreate&X
+14) Fix bug in %U expansion
+
+
+
+----------------------------------------------------------------------
+The release notes for 2.2.6 follow :
+
+There have been several fixes and internal enhancements which include:
+
+ * Fixes for MS-RPC printing issues affecting Windows 2000 clients
+ * New support for smb.conf generation in SWAT
+ * Inclusion of several performance enhancements (See --with-sendfile
+ & and the modified smb.conf(5) parameters in these Release Notes)
+ * Fixes for several file locking bugs and returned status codes
+
+
+New Parameters
+--------------
+
+Refer to the smb.conf(5) man page for complete descriptions of new
+parameters.
+
+ * profile acls (S) workaround for issue with WinXP SP1
+ and roaming user profiles
+
+Removed Parameters
+------------------
+
+ * max packet (G)
+ * packet size (G)
+
+Modified Parameters
+-------------------
+
+ * max xmit (G) new default value
+ * large readwrite (G) new default value
+
+New ./configure Options
+-----------------------
+
+ --with-sendfile Enable experimental sendfile support
+ --with-winbind-ldap-hack Enable winbindd_ldap_hack() functionality
+ for Windows 2000 native mode domains
+
+
+Changes since 2.2.5
+--------------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) Fixed several compiler warnings caused by the use of const parameters
+2) Fixed a hang in the main smbd process caused by an EINTR in the
+ wrong place
+3) Fixed string substitutions to accept a length for sanity checks
+4) Fixed 17-bit length field in nmb header
+5) Removed non-portable inline declaration for functions
+6) Performance fix for including files with an smb.conf variable in the
+ path name
+7) Fix for parsing LPRng lpq output
+8) Parsing fix for PRINTER_INFO_2 structure which was causing viewing
+ printer properties to fail
+9) Fix for printer change notification and Windows NT clients which caused
+ the client to go into an infinite loop of refreshing the local printers
+ folder
+10) Allow trans2 and nttrans messages to be processed in oplock break state
+ which fixes a problem with oplock break requests and Win2k clients
+11) Don't crash on setfileinfo on printer fsp
+12) Memory fixes caught by Valgrind
+13) Updates to stop spurious error message in tdb
+14) Fix silly logic bug in 'make smbd processes' and 'status = no' check
+15) Fix compilation of pam_smbpass and --with-ldap
+16) Fix compilation of smbwrapper on Solaris hosts
+17) fix logic error in a check for enabling the winbind_pam_auth_crap() code
+ & fix formatting typo in --with-winbind-auth-challenge
+18) Correcting check for ldap_start_tls()
+19) Fixed a problem with getgroups() where it could include our current
+ effective gid
+20) fix incorrect semantics in the DeletePrinterDriver() spoolss rpc
+ to only attempt to delete the architecture specified by the client
+21) Don't allow TEMP attribute on directory open
+22) Restore VxFS quotas to the 2.2 branch
+23) Added basic "Wizard" functionality to SWAT
+24) Fix initial "allocation size" in NTcreate&X call
+25) Fix for open fid, "nametoolong"
+26) Exit server on receipt of a non-SMB packet. Ensure we have
+ at least smb_size bytes before processing a packet
+27) Replace inet_aton with inet_addr() to correct compile problems on Solaris
+28) Include the "account" objectclass when adding a new account to --with-ldapsam
+ in order to comply with the data model implemented by OpenLDAP 2.1.x
+29) Various fixes for POSIX compliance
+30) Correct alignment & offset bug in EnumPrinterDataEx()
+31) Fix access checks when modifying forms using a print server handle
+ (not just a printer handle)
+32) Account for case data_len == 0 in EnumPrinterDataEx()
+33) Fix logic error in blocking lock code
+34) Fixed various incorrect return codes to clients
+35) Add RESOLVE_DFSPATH to mkdir operations
+36) Fix longstanding bug in Win2k clients by clearing the shortname
+ buffer before returning ASCII short name
+37) added -t option to smbpasswd for explicitly changing a trust
+ account password when operating in security = domain
+38) installed -x option to testparm to eXclude printing all parameter
+ values that are at default settings.
+39) Fix shares/printers view in SWAT so that only Basic options are exposed
+ upon initial entry.
+40) Added 1125 & KOI8-U to codepage list in Makefile.in
+41) Include separate configure checks for *openbsd* & *freebsd* when
+ determining flags used to compile shared libraries.
+42) Merge in free list unlock on error fix
+43) Correctly fail opens with mismatching SYSTEM or HIDDEN attributes
+ if we are mapping system or hidden
+44) Fix bug with stat mode open being done on read-only open with truncate
+45) Fix crash bug discovered where cli struct was being deallocated in a
+ called function
+46) Ensure we open UNIX fifo's non-blocking
+47) Fix DeletePrinterDriver() (hopefully for the last time...yeah right....)
+48) only lowercase global_myname in the %L substitution, not the whole string
+49) Merged Steve French's fix for OS/2 EA return error being removed
+50) Patch from Steve French to fix difference in responses to smbclient
+ //server/share ls / on Samba and Windows 2000
+51) Print error and exit if smb.conf doesn't have security=domain and
+ encrypt passwords=yes when joining domain
+52) Added final Steve French patch for "required" attributes with old dir
+ listings
+53) Initialize user_rid value in WINBIND_USERINFO structure returned by
+ the rpc version of query_user()
+54) Ensure we've failed a lock with a lock denied message before automatically
+ pushing it onto the blocking queue
+55) Add experimental --with-sendfile code
+56) alignment fix in printing code merged from HEAD
+57) Merge fix for other sids in token from HEAD
+58) Merge winbindd with current (more advanced) state of play in APPLIANCE_HEAD
+59) fix smbclient / Win98 off by one bug
+60) Never, *ever* hold a mutex lock in the message database where there may be
+ traversals being attempted
+61) Add LDAP hack for retrieving the SAM sequence number when a member of a
+ Windows 2000 native mode domain
+62) Fix race condition when changing a machine account password as we were
+ no longer locking the secrets entry
+63) Allow '@' as a valid character in domain names
+64) remove jobs from the spool directory when using cups
+65) removed -lresolv for --enable-ldapsam
+66) Memory leak fix and correct use of negative caching in winbindd
+67) Updated spoolss parsing code with known good state of APPLIANCE_HEAD
+68) Delete printer security check was reversed
+69) Windows allows delete printer on a handle opened by an admin user, then
+ used on a pipe handle created by an anonymous user...We do to now...
+70) Make explicit the difference between a tdb key with no data attached, and
+ a non existent entry
+71) Ensure we register the 1c name on the unicast subnet.
+72) Fix inheritance problem when recursively setting ACLs on directories
+73) prevent ACL set on read-only share
+74) Ensure we never have more than MAX_PRINT_JOBS in a queue
+75) Added timeout to tdb_lock_bystring()
+76) Ensure we set FIRST+LAST flags on a bind request
+77) Add version strings to the usage message for smbcacls and smbpasswd
+78) Fix bug in the write cache code
+79) make the default printed values for boolean the same for all parameters
+80) Default all LDAP connections to v3 with compiling with --with-ldapsam
+81) Fix memory leak in smbspool
+82) Fix bug in mangling code that resulted in Win9x clients not being
+ able to execute batch files in deep, non 8.3 directory paths
+83) Fix infinite looping bug in winbindd_getgrent()
+84) Fix crash bug on 64-bit systems (merge from HEAD)
+85) Fix extended character bug when setting LanMan/NT password
+86) Negotiate same SMB read size as a Windows 2000 file server
+ to fix performance bug with NT4 clients
+
+
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.5 follow :
+
+There have been several fixes and internal enhancements which include:
+
+* Several compile fixes for Solaris and HP-UX
+* More printing fixes for Windows NT/2k/XP clients
+* New options for the VFS recycle bin library
+* New internal signal handling semantics relating to directory change
+ notification and oplocks
+
+New/Changed parameters in 2.2.5
+--------------------------------
+
+For more information on these parameters, see the man pages for
+smb.conf(5).
+
+Added/changed parameters
+------------------------
+
+* block size = <INTEGER>
+* force unknown acl user = <boolean>
+* mangling method = [hash|hash2]
+
+
+Deprecated Parameters
+---------------------
+
+The following parameters have been marked as deprecated and will be removed
+in Samba 3.0
+
+* strip dot
+* status
+
+
+Removed Parameters
+------------------
+
+ none
+
+
+Changes in 2.2.5
+----------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) Removal of several compiler warnings, incorrect Makefile dependencies,
+ and wrong autoconf tests on various platforms--Solaris & HP-UX 10.20
+ being the predominantly reported platforms
+2) Fixed winbindd crash bug on the IBM s390 running Linux
+3) Inclusion of enhanced Linux quota support
+4) Correctly link against Sun LDAP libraries on Solaris 8 (even through
+ there is no apparent SSL support there)
+5) POSIX conformance patches
+6) Include new configure --enable-cups option (can also be disabled even
+ if CUPS libraries are installed on the system)
+7) Set reasonable default for the "passwd program" parameter using an
+ autoconf test
+8) Added --with-winbind-auth for enabling winbindd_pam_auth_crap() code
+9) fixed bug to prevent root account from being deleted by the
+ "delete user script"
+10) Inclusion of autoconf script for building VFS modules
+11) Add new run time options to the VFS recycle bin library (see
+ examples/VFS/recycle/README for details)
+12) Include findsmb perl script as part of the "make install" process
+13) Return correct error code for EnumPrinters(PRINTER_ENUM_REMOTE, InfoLevel1)
+ to fix a bug where printers appear at the workgroup level in the Windows
+ NT/2k APW browse list
+14) Added support to nmblookup to return NMB flags (See nmblookup(8) for
+ details)
+15) Fix length bug that caused password changes from Windows NT/2k clients to
+ occasionally fail
+16) Correct false password expiration when using --with-ldapsam caused by
+ missing attributes in the directory
+17) added -S option to smbpasswd for storing the SID of a domain controller
+ as the local machine SID in secrets.tdb. See the smbpasswd(8) man page
+ for details.
+18) Various fixes for UNIX CIFS extensions commands
+19) Fixed CIDR notation in "hosts allow/deny"
+20) Change semantics of an idle connection to mean "no open files and no
+ open handles". We cannot idle a connection if there are open named
+ pipe handles. This fixes scalability problem on Samba print servers
+ and NT/2k clients introduced in 2.2.4
+21) Fix germam umlaut problem when returning ACL entries
+22) Return NT_STATUS_OBJECT_NAME_NOT_FOUND for ENOENT. This fixes the bug
+ of running the Microsoft Access executable (msaccess.exe) and database
+ files from a Samba share documented in the 2.2.4 release
+23) Corrected signal handling relating to directory change notification and
+ kernel oplocks
+24) Fix bug in unix_to_nt_time() that appeared on files dated close to Daylight
+ Savings Time
+25) Corrected alignment bug in spoolss parsing code which caused Win2k/XP
+ clients not to be able to view printer properties from a Samba host
+26) Fixed spoolss parsing bug causing printing from ACT! 2000 running on
+ Windows 2k/XP clients to fail
+27) Fixed incorrect error check in mod_share_entry()
+28) Allow %S variable in MS-DFS root paths
+29) Correct a bug regarding the use of 'wbinfo -A'
+30) Fixed libnss_wins.so to correctly work on RedHat 7.3 systems
+31) Store the key for a name-to-sid cache entry in upper case rather than
+ whatever case the request was made in. This gets rid of duplicate
+ cache entries.
+32) Fix bug causing the pid stored in winbindd's pid file to be the wrong id
+33) Enhanced error reporting messages of wbinfo
+34) Parameterize block size on disk size return
+35) Added new parameter to allow incoming ACLs to have owner and group forced
+ to the currently logged in user. This fixes the XCOPY /O problem
+36) Fixed bug in local_change_password() caused by reusing a struct
+ passwd* pointer
+37) Change default value for "ldap port" to 389 if "ldap ssl = no"
+38) Updated HOWTO's, manpages, and general documentation....
+39) Allow root as well as domain admins to open an LDAP connection
+40) Fixed veto files bug with ".*"
+41) Fixed uninitialized variable bug in smbpasswd that was causing a random
+ IP address to be used in the connection when joining a domain
+42) Fix for joining a domain with a netbios name of 15 characters and
+ pre-creating the account on the DC
+43) Added links to new documentation on SWAT welcome page
+
+
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.4 follow :
+
+There have been several fixes and internal enhancements which include:
+
+ * More/better SPOOLSS printing functionality for Windows
+ NT/2k/XP clients.
+ * Several fixes relating to serving PC database files such
+ as (Access and FoxPro) from a Samba file share.
+ * Several improves in Samba's VFS layer which can be seen
+ in the inclusion of a "Recycle Bin" vfs module. See
+ examples/VFS/README for more details on this.
+ * Addition of a tool (tdbbackup) for backup/restore of Samba's
+ tdb's
+ * Continued improvements to winbind for greater scalability
+ and stability
+ * Several fixes related to Samba's MS-DFS support
+ * Rpcclient's various printer commands now work (again)
+
+
+New/Changed parameters in 2.2.4
+--------------------------------
+
+For more information on these parameters, see the man pages for
+smb.conf(5).
+
+Added/changed parameters
+------------------------
+
+* csc policy
+* inherit acls
+* nt status support
+* lock spin count
+* lock spin time
+* pid directory
+* winbind use default domain
+
+
+Deprecated parameters
+---------------------
+
+The following parameters have been marked as deprecated
+and will be removed in Samba 3.0
+
+* postscript
+* printer driver
+* printer driver file
+* printer driver location
+
+
+Removed Parameters
+------------------
+
+ none
+
+
+Changes in 2.2.4
+----------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) added -c option to smbpasswd
+2) reworked smbpasswd internal command line option parsing
+3) small various bug fixes to experimental pdb_tdb.c
+4) Enforce spoolss RPCs based on the access granted at PrinterOpen()
+5) Added missing access checks to [add/delete/set]form
+6) Compile fixes for pam_smbpass
+7) fix smbd crash when netbios session request fails from
+ spoolss_connect_to_client().
+8) fixed logic bug that prevent SetPrinter() from storing devmode
+9) Removed extra get_printer_snum() calls from set_printer_hnd_name()
+10) fix joining domain on big endian machine when using -U to smbpasswd
+11) allow command line arg to override smb.conf log level
+12) continue to retry to register 1b name with wins server if there is an old IP there
+13) fix smbclient print crash bug
+14) 9x pnp fix when the config file and driver file are different
+15) force testparm to print the correct value for log level
+16) fix swat to show full log level info
+17) fix server GetPrinterData() fields to be more sensible
+18) fix logic error in SetPrinterDataEx()
+19) Only set smb_read_error if not already set
+20) Fix string returns that require unicode
+21) Merge of printing performance fixes from appliance
+22) lpq parsing fixes
+23) Back port tridge's xcopy /o fix from HEAD
+24) Fix the printer change notify code (unfinished)
+25) Patch for Domain users not showing up
+26) Fixed SetPrinterData(magic key) to support zero length DEVMODE
+27) Ensure that all methods of looking up and connecting to DC's work
+ using identical logic.
+28) Merge in the mutex code to stop multiple domain logon failure
+29) Ignore 0/0 lock
+30) Fix winbindd to respect command line debuglevel as nmbd/smbd
+31) Update with tdbbackup from HEAD
+32) Fix for typo on solaris nss
+33) Merge in the locking changes from HEAD
+34) Added POSIX ACL layer into the vfs
+35) Fix the returning of domain enum
+36) Fix the generation of the MACHINE.SID file into the secrets.tdb.
+37) Enable test for -rdynamic when building binaries
+38) Remove the "stat open" code - make it inline
+39) Fix the mp3 rename bug
+40) Fix for Explorer DFS problems on older Windows 9X machines
+41) implement OpenPrinter() opnum == 0x01
+42) Matched W2K *insane* open semantics....
+43) small fix that will prevent the "failed to marshall
+ R_NET_SAMLOGON" message in the logs
+42) don't do checking of local passdb in smbpasswd if using -r option
+43) fix "smbpasswd -j DOMAIN -r * -U Admin%XXXX" so that it doesn't
+ try to connect to a server named '*'
+44) merge rpcclient code from HEAD
+45) Ensure MACHINE.SID update done before child spawns
+46) Fix the bad path errors for mkdir so mkdir \a\b\c\d works
+47) Removed --with-vfs - always built if available
+48) Fixed psec for 2.2
+49) Fixed the handle leak in the connection management code
+50) fix disable spoolss after the switch to nt status codes
+51) Added Shirish's client side caching policy change
+52) Honor the specversion when parsing the the DEVICEMODE
+53) fix parsing bug when DEVICEMODE's private data does not end
+ on a 4 byte boundary
+54) do not idle an smbd when there is an open pipe
+55) when a new driver is added to a Samba server, cycle through
+ all printers and bump the change_id for each one bound to the driver
+56) allow smbclient to work with a FIFO as well (needed for KDE
+ ioslave)
+57) various updates to pdb_nisplus.c
+58) many small documentation updates
+59) removed many compiler warnings
+
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.3a follow :
+
+This is a minor bugfix release for the 2.2.3 release. The 2.2.3
+release had a problem that was visible to Windows 2000 Explorer
+users in that copying files into a share that already existed
+failed with "Access Denied" rather than asking the user if an
+overwrite was required. This was due to an incorrect error mapping
+between the UNIX EXIST error code and the NT status error.
+
+As Windows Explorer is a highly visible end user application a quick
+bugfix release was required, hence 2.2.3a.
+
+Compilation on HP-UX versions earlier than HP-UX 11 has also been
+corrected.
+
+The cvs.log file is no longer included with this release, as it adds
+13Mb to the size of the release, and is easily available on the Web.
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.3 follow :
+
+There are several important scaling bugs that have been fixed in this release
+for large server systems so an upgrade is recommended.
+
+LDAP update
+-----------
+
+Much work has been done on the LDAP backend code. The configure
+option --with-ldapsam is now considered to be stable. The schema
+used has changed, see the file examples/LDAP/samba.schema for the
+new schema.
+
+New documentation explaining how to set up a Samba only PDC/BDC
+setup has been added in the files Samba-LDAP-HOWTO and Samba-BDC-HOWTO
+in the documentation tree.
+
+winbindd daemon extended
+------------------------
+
+Samba 2.2.2 was the first release to include the winbind daemon.
+This code allows UNIX systems that implement the name service
+switch (nss) to be entered into a Windows NT/2000 domain and
+use the Domain controller for all user and group enumeration.
+
+Samba 2.2.3 fixes the known memory leaks in winbindd and has
+been extended to work with SGI IRIX and HP-UX (11.x) in addition
+to the earlier targets of Linux and Solaris.
+
+For more information on using winbind, see the man pages for
+winbindd and wbinfo.
+
+Note that winbindd is not installed by default.
+
+New/Changed parameters in 2.2.3
+--------------------------------
+
+For more information on these parameters, see the man pages for
+smb.conf.
+
+Added/changed parameters.
+-------------------------
+
+unix extensions
+
+Enables the experimental UNIX CIFS extensions in smbd. See the manpage
+for more details.
+
+default devmode
+
+Some printer drivers will crash the Windows NT/2000 spooler service
+if they are given a default devmode, some require it. This parameter
+allows the administrator a choice of whether smbd returns such a
+default devmode for a driver.
+
+share modes
+
+This parameter has been restored to allow people who wish smbd to ignore
+client share modes. This is *very dangerous* and should not be set without
+full knowledge of what this is designed for.
+
+Changes in 2.2.3
+-----------------
+
+1). Fixed shared library compile for Solaris with native compiler.
+2). UNIX CIFS extensions code added (donated by HP).
+3). Changed to using NT status codes on the wire if the client can support
+this.
+4). altname command to show 8.3 name added to smbclient.
+5). const-safe endian macros now used.
+6). client code now uses UNICODE on the wire.
+7). Correctly return fault PDU's on bad handle.
+8). Improved NT error code mapping table.
+9). Many new point and print RPC calls added.
+10). Win9x clients can now see full user list.
+11). field added to identify simultaneous open files (no longer
+use dev/inode/time as unique value).
+12). HP-UX ACL code added (donated by HP).
+13). vfs interfaces updated (again !).
+14). MSDOS Code Page 866 -> 1251 mapping added.
+15). winbindd now processes quit/hup signals correctly.
+16). No tdb traversal done on startup/shutdown - ensures scalability.
+17). Fix bug with paths for homes share.
+18). Fixed copyfile for OS/2.
+19). Fix group membership when groups are on more than one line.
+20). Fixed core dumps in posix ACL mapping code.
+21). Tidyup of UNICODE functions (put/get).
+22). Move rpcclient to the new libsmb code.
+23). Add missing Windows 2000 passthough trans2 calls.
+24). Return check all tdb calls.
+25). Make local name lookup work even if wins server is down.
+26). pam session code added to winbind.
+27). Added winbindd cache to all lookups.
+28). Fix allocate bugs that caused file sizes to be incorrect.
+29). Fixed write cache code - now safe to use.
+30). Fixed winbindd memory leaks.
+31). winbindd will now do name lookups (to allow non Open Source
+systems to do the nsswitch WINS lookup). Fixed by SGI.
+32). passdb memory leaks fixed.
+33). LDAP code updates and now properly maintained.
+34). Finally figured out how changeid is meant to work.
+35). Downlevel printing now looks as NT does in print monitor window.
+36). Many fixups in spoolss printing RPC parsing.
+37). Speed up password enumeration as a PDC.
+38). Fix printer changed notify messages (work from HP).
+39). Fix modify timestamp on close code.
+40). Fix long standing mangled names bug.
+41). Fix delete on close semantics.
+42). Stop opening all files with O_NONBLOCK !
+43). Use O_NOFOLLOW for systems that have it and don't want symlinks.
+44). Ensure NT supplementary groups get added to user token.
+45). Try and mitigate effects of DNS timeout (do less lookups).
+46). Added current user connection context stack.
+47). Fixes to utmp code.
+48). smbw code tidyups.
+49). Added tdb open log code. Several tdb fixes.
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.2 follow :
+
+New daemon included - winbindd
+------------------------------
+
+Samba 2.2.2 is the first release to include the winbind daemon.
+This code allows UNIX systems that implement the name service
+switch (nss) to be entered into a Windows NT/2000 domain and
+use the Domain controller for all user and group enumeration.
+
+This allows a Samba server added to a Windows domain to serve
+file and print services with *NO* local users needed in /etc/passwd
+and /etc/group - all users and groups are read directly from the
+Windows domain controller. In addition with pam_winbind which allows
+a PAM enabled UNIX system to use a Windows domain for authentication
+service this allows single sign on and account control across
+UNIX and Windows systems.
+
+The current version of winbindd shipped in 2.2.2 does have some
+memory leaks, which will be addressed for the next Samba release,
+so it is advisable to monitor the winbind process. This code is
+being used in production by several vendors, so the leaks are
+manageable. In addition, this version of winbind does not work
+correctly against a Samba PDC, due to some missing calls on the
+PDC side. These problems are being addressed for the next Samba
+release, but it was thought better to release the code now rather
+than delay the main Samba code to match the winbind release schedule.
+
+For more information on using winbind, see the man pages for
+winbindd and wbinfo.
+
+Note that winbindd is not installed by default.
+
+New/Changed parameters in 2.2.2
+-------------------------------
+
+For more information on these parameters, see the man pages for
+smb.conf.
+
+Added/changed parameters.
+-------------------------
+
+strict allocate
+
+Causes Samba not to create UNIX 'sparse' files, but to follow the
+Windows behavior of always allocating on-disk space.
+
+use mmap
+
+Set to 'on' by default, only set to 'off' on HP-UX 11.x or below or other
+UNIX systems that don't have coherent mmap/read-write internal caches.
+You should not need to set this parameter.
+
+nt acl support
+
+This parameter has been changed to a per-share option, and is very
+useful in enabling Windows 2000 SP2 to load/save profiles from a
+Samba share.
+
+New printing parameters.
+------------------------
+
+disable spoolss
+
+Setting this parameter causes Samba to go back to the old 2.0.x
+LANMAN printing behavior, for people who wish to disable the
+new SPOOLSS pipe.
+
+use client driver
+
+Causes Windows NT/2000 clients to need have a local printer driver
+installed and to treat the printer as local.
+
+New LDAP parameters.
+--------------------
+
+Samba 2.2.2 contains new code to maintain a Samba SAM database
+on a remote LDAP server. These parameters have been added as
+part of this code. These parameters are only available when Samba
+has been compiled with the --with-ldapsam option.
+
+ldap admin dn
+ldap ssl
+
+New SSL parameters.
+-------------------
+
+The SSL support in Samba has been fixed. These new parameters
+are part of the changes added. These parameters are only available
+when Samba has been compiled with the --with-ssl option.
+Please see the smb.conf man page for details.
+
+ssl egd socket
+ssl entropy file
+ssl entropy bytes
+
+New winbindd parameters.
+------------------------
+
+These parameters are used by winbindd. See the man page for
+winbindd for details.
+
+winbind separator
+winbind uid
+winbind gid
+winbind cache time
+winbind enum users
+winbind enum groups
+template homedir
+template shell
+
+Removed parameters.
+-------------------
+
+share modes
+ldap root
+ldap root passwd
+
+New Documentation.
+------------------
+
+Some new README's have been added in the docs/ directory. These cover
+using roving profiles with Windows 2000 SP2 (docs/README.Win2kSP2),
+and how to use Samba to help prevent Windows virus spread
+(docs/README.Win32-Viruses).
+
+Quota problems on a Linux 2.4 kernel.
+-------------------------------------
+
+Currently the quota interfaces have diverged between the Linus
+2.4.x kernels and the Alan Cox 2.4.x kernels (the Alan Cox variants
+are shipped with RedHat). Running quota-enabled Samba compiled on
+an Alan Cox kernel works correctly on an Alan Cox kernel (the one
+shipped by default with RedHat 7.x) but fails on a Linus kernel.
+
+This is a mess, and hopefully Alan and Linus will sort it out soon.
+In the meantime we need to ship.....
+
+Changes in 2.2.2
+-----------------
+
+1). mmap tdb code disabled on HP-UX. This should prevent the reports of
+tdb corruption on HUPX.
+2). Large file support set to off in Solaris 5.5 and below.
+3). Better CUPS detection.
+4). New SAM (password database) backends - smbpasswd (traditional),
+LDAP, NIS+ and Samba TDB.
+5). Quota fixups on Linux.
+6). libsmbclient stand-alone code added. Can be built as a shared library
+under Linux.
+7). Tru64 ACL support added.
+8). winbindd option added.
+9). Realloc fail tidyup fixes all over the code.
+10). Large improvement in hash table code efficiency - would be found with
+large stat caches.
+11). Error code consistency improved (still needs more work).
+12). Profile shared memory support added to nmbd.
+13). New Windows 2000/NT passthrough info levels added.
+14). readraw/writeraw code rewritten - many bugs fixed.
+15). UNIX password sync (non pam) code fixed, use correct wildcard matcher.
+16). Reverse DNS lookup avoided on socket open.
+17). Bug preventing nmbd re-registering names on WINS server timeout fixed.
+18). Zero length byte range lock code added. Much closer to Windows semantics.
+19). Alignment fault fixes for Linux/Alpha.
+20). Error checking on tdb returns vastly improved.
+21). Handling of delete on close fixed. No longer possible to leave 'dead'
+file entries.
+22). Handling of oplock break failure cleanups improved. Should not be
+able to leave 'dead' entries.
+23). Fix handling of errors trying to set 64 bit locks on 32 bit NFS mounts.
+24). Misc. MS-DFS code fixes.
+25). Ignore logon packets if not a PDC (needed for PDC/BDC failover).
+26). winbind pam module added.
+27). Order N^^2 enumeration of printers problem fixed.
+28). Password backend database code re-ordered to allow different password
+backends (at compile time currently).
+29). Improved print driver version detection for Windows 2000.
+30). Driver DEVMODE initialization fixes.
+31). Improved SYSV print parse code.
+32). Fixed enumeration of large numbers of users/groups from Windows clients.
+Code still too slow.
+33). Fix for buggy NetApp RPC pipe clients.
+34). Fix for NT sending multiple SetPrinterDataEx calls.
+35). Fix for logic bug where smbd could delay oplock break request messages
+from other smbd daemons whilst client kept us busy.
+36). Fix deadlock problem with connections tdb on enumeration.
+37). Fixes for setting/getting NT ACLs - improved POSIX mapping both ways.
+38). Removed unused readbmpx/writebmpx code.
+39). Attempt to fix Linux 2.4.x quota mess.
+40). Improved ctemp code for Windows 2000 compatibility.
+41). Finally understood difference between set EOF and set allocation requests.
+Added strict allocate parameter to help.
+42). Correctly return name types on name to SID lookups.
+43). tdb spinlock code update.
+44). Use pread/pwrite on systems that have it to fix race condition in tdb code.
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.1a follow :
+
+This is a minor bugfix release for 2.2.1, *NOT* security related.
+
+1). 2.2.1 had a bug where using smbpasswd -m to add a Windows NT or
+Windows2000 machine into a Samba hosted PDC would fail due to our
+stricter user name checking. We were disallowing user names
+containing '$', which is needed when using smbpasswd to add a
+machine into a domain. Automatically adding machines (using the
+native Windows tools) into a Samba domain worked correctly.
+
+2.2.1a fixes this single problem.
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.1 follow :
+
+New/Changed parameters in 2.2.1
+-------------------------------
+
+Added parameters.
+-----------------
+
+obey pam restrictions
+
+When Samba is configured to use PAM, turns on or off Samba checking
+the PAM account restrictions. Defaults to off.
+
+pam password change
+
+When Samba is configured to use PAM, turns on or off Samba passing
+the password changes to PAM. Defaults to off.
+
+large readwrite
+
+New option to allow new Windows 2000 large file (64k) streaming
+read/write options. Needs a 64 bit underlying operating system
+(for Linux use kernel 2.4 with glibc 2.2 or above). Can improve performance
+by 10% with Windows 2000 clients. Defaults to off. Not as tested
+as some other Samba code paths.
+
+hide unreadable
+
+Prevents clients from seeing the existence of files that cannot
+be read. Off by default.
+
+enhanced browsing
+
+Turn on/off the enhanced Samba browsing functionality (*1B names).
+Default is "on". Can prevent eternal machines in workgroups when
+WINS servers are not synchronized.
+
+Removed parameters.
+-------------------
+
+domain groups
+domain admin users
+domain guest users
+
+Changes in 2.2.1
+-----------------
+
+1). "find" command removed for smbclient. Internal code now used.
+2). smbspool updates to retry connections from Michael Sweet.
+3). Fix for mapping 8859-15 characters to UNICODE.
+4). Changed "security=server" to try with invalid username to prevent
+ account lockouts.
+5). Fixes to allow Windows 2000 SP2 clients to join a Samba PDC.
+6). Support for Windows 9x Nexus tools to allow security changes from Win9x.
+7). Two locking fixes added. Samba 2.2.1 now passes the Clarion network
+ lock tester tool for distributed databases.
+8). Preliminary support added for Windows 2000 large file read/write SMBs.
+9). Changed random number generator in Samba to prevent guess attacks.
+10). Fixes for tdb corruption in connections.tdb and file locking brlock.tdb.
+ smbd's clean the tdb files on startup and shutdown.
+11). Fixes for default ACLs on Solaris.
+12). Tidyup of password entry caching code.
+13). Correct shutdowns added for send fails. Helps tdb cleanup code.
+14). Prevent invalid '/' characters in workgroup names.
+15). Removed more static arrays in SAMR code.
+16). Client code is now UNICODE on the wire.
+17). Fix 2 second timestamp resolution everywhere if dos timestamp set to yes.
+18). All tdb opens now going through logging function.
+19). Add pam password changing and pam restrictions code.
+20). Printer driver management improvements (delete driver).
+21). Fix difference between NULL security descriptors and empty
+ security descriptors.
+22). Fix SID returns for server roles.
+23). Allow Windows 2000 mmc to view and set Samba share security descriptors.
+24). Allow smbcontrol to forcibly disconnect a share.
+25). tdb fixes for HP-UX, OpenBSD and other OS's that don't have a coherent
+ mmap/file read/write cache.
+26). Fix race condition in returning create disposition for file create/open.
+27). Fix NT rewriting of security descriptors to their canonical form for
+ ACLs.
+28). Fix for Samba running on top of Linux VFAT ftruncate bug.
+29). Swat fixes for being run with xinetd that doesn't set the umask.
+30). Fix for slow writes with Win9x Explorer clients. Emulates Microsoft
+ TCP stack early ack specification error.
+31). Changed lock & persistent tdb directory to /var/cache/samba by default on
+ RedHat and Mandrake as they clear the /var/lock/samba directory on reboot.
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.0a follow :
+
+SECURITY FIX
+============
+
+This is a security bugfix release for Samba 2.2.0. This release provides the
+following two changes *ONLY* from the 2.2.0 release.
+
+1). Fix for the security hole discovered by Michal Zalewski (lcamtuf@bos.bindview.com)
+ and described in the security advisory below.
+2). Fix for the hosts allow/hosts deny parameters not being honoured.
+
+No other changes are being made for this release to ensure a security fix only.
+For new functionality (including these security fixes) download Samba 2.2.1
+when it is available.
+
+The security advisory follows :
+
+
+ IMPORTANT: Security bugfix for Samba
+ ------------------------------------
+
+June 23rd 2001
+
+
+Summary
+-------
+
+A serious security hole has been discovered in all versions of Samba
+that allows an attacker to gain root access on the target machine for
+certain types of common Samba configuration.
+
+The immediate fix is to edit your smb.conf configuration file and
+remove all occurances of the macro "%m". Replacing occurances of %m
+with %I is probably the best solution for most sites.
+
+Details
+-------
+
+A remote attacker can use a netbios name containing unix path
+characters which will then be substituted into the %m macro wherever
+it occurs in smb.conf. This can be used to cause Samba to create a log
+file on top of an important system file, which in turn can be used to
+compromise security on the server.
+
+The most commonly used configuration option that can be vulnerable to
+this attack is the "log file" option. The default value for this
+option is VARDIR/log.smbd. If the default is used then Samba is not
+vulnerable to this attack.
+
+The security hole occurs when a log file option like the following is
+used:
+
+ log file = /var/log/samba/%m.log
+
+In that case the attacker can use a locally created symbolic link to
+overwrite any file on the system. This requires local access to the
+server.
+
+If your Samba configuration has something like the following:
+
+ log file = /var/log/samba/%m
+
+Then the attacker could successfully compromise your server remotely
+as no symbolic link is required. This type of configuration is very
+rare.
+
+The most commonly used log file configuration containing %m is the
+distributed in the sample configuration file that comes with Samba:
+
+ log file = /var/log/samba/log.%m
+
+in that case your machine is not vulnerable to this attack unless you
+happen to have a subdirectory in /var/log/samba/ which starts with the
+prefix "log."
+
+Credit
+------
+
+Thanks to Michal Zalewski (lcamtuf@bos.bindview.com) for finding this
+vulnerability.
+
+
+New Release
+-----------
+
+While we recommend that vulnerable sites immediately change their
+smb.conf configuration file to prevent the attack we will also be
+making new releases of Samba within the next 24 hours to properly fix
+the problem. Please see http://www.samba.org/ for the new releases.
+
+Please report any attacks to the appropriate authority.
+
+ The Samba Team
+ security@samba.org
+
+---------------------------------------------------------------------------
+
+The release notes for 2.2.0 follow :
+
+This is the official Samba 2.2.0 release. This version of Samba provides
+the following new features and enhancements.
+
+Integration between Windows oplocks and NFS file opens (IRIX and Linux
+2.4 kernel only). This gives complete data and locking integrity between
+Windows and UNIX file access to the same data files.
+
+Ability to act as an authentication source for Windows 2000 clients as
+well as for NT4.x clients.
+
+Integration with the winbind daemon that provides a single
+sign on facility for UNIX servers in Windows 2000/NT4 networks
+driven by a Windows 2000/NT4 PDC. winbind is not included in
+this release, it currently must be obtained separately. We are
+committed to including winbind in a future Samba 2.2.x release.
+
+Support for native Windows 2000/NT4 printing RPCs. This includes
+support for automatic printer driver download.
+
+Support for server supported Access Control Lists (ACLs).
+This release contains support for the following filesystems:
+
+ Solaris 2.6+
+ SGI Irix
+ Linux Kernel with ACL patch from http://acl.bestbits.at
+ Linux Kernel with XFS ACL support.
+ Caldera/SCO UnixWare
+ IBM AIX
+ FreeBSD (with external patch)
+
+Other platforms will be supported as resources are
+available to test and implement the necessary modules. If
+you are interested in writing the support for a particular
+ACL filesystem, please join the samba-technical mailing
+list and coordinate your efforts.
+
+On PAM (Pluggable Authentication Module) based systems - better debugging
+messages and encrypted password users now have access control verified via
+PAM - Note: Authentication still uses the encrypted password database.
+
+Rewritten internal locking semantics for more robustness.
+This release supports full 64 bit locking semantics on all
+(even 32 bit) platforms. SMB locks are mapped onto POSIX
+locks (32 bit or 64 bit) as the underlying system allows.
+
+Conversion of various internal flat data structures to use
+database records for increased performance and
+flexibility.
+
+Support for acting as a MS-DFS (Distributed File System) server.
+
+Support for manipulating Samba shares using Windows client tools
+(server manager). Per share security can be set using these tools
+and Samba will obey the access restrictions applied.
+
+Samba profiling support (see below).
+
+Compile time option for enabling a (Virtual file system) VFS layer
+to allow non-disk resources to be exported as Windows filesystems
+(such as databases etc.).
+
+The documentation in this release has been updated and converted
+from Yodl to DocBook 4.1. There are many new parameters since 2.0.7
+and some defaults have changed.
+
+Profiling support.
+------------------
+Support for collection of profile information. A shared
+memory area has been created which contains counters for
+the number of calls to and the amount of time spent in
+various system calls, smb transactions and nmbd activity. See
+the file profile.h for a complete listing of the information
+collected. Sample code for a samba pmda (collection agent
+for Performance Co-Pilot) has been included in the pcp
+directory.
+
+To enable the profile data collection code in samba, you must
+compile samba with profile data support (run configure with
+the --with-profiling-data option). On startup, collection of
+data is disabled. To begin collecting data use the smbcontrol
+program to turn on profiling (see the smbcontrol man page).
+Profile information collection can be enabled for nmbd, all smbd
+processes or one or more selected processes. The profiling
+data collected is the aggregate for all processes that have
+profiling enabled.
+
+With samba compiled for profile data collection, you may see
+a very slight degradation in performance even with profiling
+collection turned off. On initial tests with NetBench on an
+SGI Origin 200 server, this degradation was not measurable
+with profile collection off compared to no profile collection
+compiled into samba.
+
+With count profile collection enabled on all clients, the
+degradation was less than 2%. With full profile collection
+enabled on all clients, the degradation was about 8.5%.
+
+=====================================================================
+
+If you think you have found a bug please email a report to :
+
+ samba@samba.org
+
+As always, all bugs are our responsibility.
+
+Regards,
+
+ The Samba Team.
diff --git a/jerry2/source/include/mangle.h b/jerry2/source/include/mangle.h
new file mode 100644
index 00000000000..d86cfd6ef1a
--- /dev/null
+++ b/jerry2/source/include/mangle.h
@@ -0,0 +1,14 @@
+#ifndef _MANGLE_H_
+#define _MANGLE_H_
+/*
+ header for 8.3 name mangling interface
+*/
+
+struct mangle_fns {
+ BOOL (*is_mangled)(const char *s);
+ BOOL (*is_8_3)(const char *fname, BOOL check_case, BOOL allow_wildcards);
+ void (*reset)(void);
+ BOOL (*check_cache)(char *s, size_t maxlen);
+ void (*name_map)(char *OutName, BOOL need83, BOOL cache83);
+};
+#endif /* _MANGLE_H_ */
diff --git a/jerry2/source/include/proto.h b/jerry2/source/include/proto.h
new file mode 100755
index 00000000000..259eff8921f
--- /dev/null
+++ b/jerry2/source/include/proto.h
@@ -0,0 +1,5092 @@
+#ifndef _PROTO_H_
+#define _PROTO_H_
+/* This file is automatically generated with "make proto". DO NOT EDIT */
+
+
+/* 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(const char *server, const char *share);
+
+/* The following definitions come from client/clitar.c */
+
+void cmd_block(void);
+void cmd_tarmode(void);
+void cmd_setmode(void);
+void cmd_tar(void);
+int process_tar(void);
+int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
+
+/* The following definitions come from lib/access.c */
+
+BOOL allow_access(char *deny_list,char *allow_list,
+ char *cname,char *caddr);
+BOOL check_access(int sock, char *allow_list, char *deny_list);
+
+/* The following definitions come from lib/bitmap.c */
+
+struct bitmap *bitmap_allocate(int n);
+void bitmap_free(struct bitmap *bm);
+BOOL bitmap_set(struct bitmap *bm, unsigned i);
+BOOL bitmap_clear(struct bitmap *bm, unsigned i);
+BOOL bitmap_query(struct bitmap *bm, unsigned i);
+int bitmap_find(struct bitmap *bm, unsigned ofs);
+
+/* The following definitions come from lib/charcnv.c */
+
+char *unix2dos_format_static(const char *str);
+char *unix2dos_format(char *str);
+char *dos2unix_format_static(const char *str);
+char *dos2unix_format(char *str);
+void interpret_character_set(char *str, int codepage);
+
+/* The following definitions come from lib/charset.c */
+
+void charset_initialise(void);
+void codepage_initialise(int client_codepage);
+void add_char_string(const char *s);
+
+/* The following definitions come from lib/crc32.c */
+
+uint32 crc32_calc_buffer( char *buffer, uint32 count);
+
+/* The following definitions come from lib/debug.c */
+
+const char* debug_classname_from_index(int ndx);
+int debug_lookup_classname(char* classname);
+BOOL debug_parse_params(char **params, int *debuglevel_class);
+BOOL debug_parse_levels(char *params_str);
+void debug_message(int msg_type, pid_t src, void *buf, size_t len);
+void debug_message_send(pid_t pid, int level);
+void setup_logging(const char *pname, BOOL interactive);
+BOOL reopen_logs( void );
+void force_check_log_size( void );
+BOOL need_to_check_log_size( void );
+void check_log_size( void );
+void dbgflush( void );
+BOOL dbghdr( int level, const char *file, const char *func, int line );
+
+/* The following definitions come from lib/error.c */
+
+NTSTATUS map_nt_error_from_unix(int unix_error);
+
+/* The following definitions come from lib/fault.c */
+
+void fault_setup(void (*fn)(void *));
+
+/* The following definitions come from lib/fsusage.c */
+
+int sys_fsusage(const char *path, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
+
+/* The following definitions come from lib/genrand.c */
+
+void set_rand_reseed_data(unsigned char *data, size_t len);
+void generate_random_buffer( unsigned char *out, int len, BOOL do_reseed_now);
+char *generate_random_str(size_t len);
+
+/* The following definitions come from lib/getsmbpass.c */
+
+char *getsmbpass(const char *prompt) ;
+
+/* The following definitions come from lib/hash.c */
+
+BOOL hash_table_init(hash_table *table, int num_buckets, compare_function compare_func);
+hash_element *hash_lookup(hash_table *table, char *key);
+hash_element *hash_insert(hash_table *table, char *value, char *key);
+void hash_remove(hash_table *table, hash_element *hash_elem);
+void hash_clear(hash_table *table);
+
+/* The following definitions come from lib/interface.c */
+
+void load_interfaces(void);
+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(const char *str);
+void initialize_multibyte_vectors( int client_codepage);
+
+/* The following definitions come from lib/md4.c */
+
+void mdfour(unsigned char *out, unsigned char *in, int n);
+
+/* The following definitions come from lib/messages.c */
+
+void ping_message(int msg_type, pid_t src, void *buf, size_t len);
+void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len);
+BOOL message_init(void);
+BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
+ BOOL duplicates_allowed);
+void message_dispatch(void);
+void message_register(int msg_type,
+ void (*fn)(int msg_type, pid_t pid, void *buf, size_t len));
+void message_deregister(int msg_type);
+BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type,
+ const void *buf, size_t len,
+ BOOL duplicates_allowed,
+ int *n_sent);
+
+/* The following definitions come from lib/ms_fnmatch.c */
+
+int ms_fnmatch(const char *pattern, const char *string);
+
+/* The following definitions come from lib/pam_errors.c */
+
+NTSTATUS pam_to_nt_status(int pam_error);
+int nt_status_to_pam(NTSTATUS nt_status);
+NTSTATUS pam_to_nt_status(int pam_error);
+int nt_status_to_pam(NTSTATUS nt_status);
+
+/* The following definitions come from lib/pidfile.c */
+
+pid_t pidfile_pid(const char *name);
+void pidfile_create(const char *name);
+
+/* The following definitions come from lib/readline.c */
+
+char *smb_readline(char *prompt, void (*callback)(void),
+ char **(completion_fn)(const char *text, int start, int end));
+void cmd_history(void);
+
+/* The following definitions come from lib/replace.c */
+
+char *rep_inet_ntoa(struct in_addr ip);
+
+/* The following definitions come from lib/select.c */
+
+void sys_select_signal(void);
+int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval);
+int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval);
+
+/* The following definitions come from lib/sendfile.c */
+
+ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
+ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
+ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
+ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
+ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
+ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
+
+/* 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 libsmb/cliconnect.c */
+
+BOOL cli_session_setup(struct cli_state *cli,
+ const char *user,
+ const char *pass, int passlen,
+ const char *ntpass, int ntpasslen,
+ const char *workgroup);
+BOOL cli_ulogoff(struct cli_state *cli);
+BOOL cli_send_tconX(struct cli_state *cli,
+ const char *share, const char *dev, const char *pass, int passlen);
+BOOL cli_tdis(struct cli_state *cli);
+void cli_negprot_send(struct cli_state *cli);
+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);
+BOOL cli_establish_connection(struct cli_state *cli,
+ const char *dest_host, struct in_addr *dest_ip,
+ struct nmb_name *calling, struct nmb_name *called,
+ const char *service, const char *service_type,
+ BOOL do_shutdown, BOOL do_tcon);
+NTSTATUS cli_full_connection(struct cli_state **output_cli,
+ const char *my_name, const char *dest_host,
+ struct in_addr *dest_ip, int port,
+ const char *service, const char *service_type,
+ const char *user, const char *domain,
+ const char *password, int pass_len) ;
+BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, const char *desthost,
+ struct in_addr *pdest_ip);
+
+/* The following definitions come from libsmb/cli_dfs.c */
+
+struct cli_state *cli_dfs_initialise(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL *dfs_exists);
+NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *entrypath, char *servername, char *sharename,
+ char *comment, uint32 flags);
+NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *entrypath, char *servername, char *sharename);
+NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *entrypath, char *servername, char *sharename,
+ uint32 info_level, DFS_INFO_CTR *ctr);
+NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 info_level, DFS_INFO_CTR *ctr);
+
+/* The following definitions come from libsmb/clidgram.c */
+
+int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot,
+ char *buf, int len,
+ const char *srcname, int src_type,
+ const char *dstname, int dest_type,
+ struct in_addr dest_ip, struct in_addr src_ip,
+ int dest_port, int src_port);
+int cli_get_response(int dgram_sock, BOOL unique, const char *mailslot, char *buf, int bufsiz);
+int cli_get_backup_list(const char *myname, const char *send_to_name);
+int cli_get_backup_server(char *my_name, char *target, char *servername, int namesize);
+
+/* The following definitions come from libsmb/clientgen.c */
+
+int cli_set_port(struct cli_state *cli, int port);
+BOOL cli_receive_smb(struct cli_state *cli);
+BOOL cli_send_smb(struct cli_state *cli);
+void cli_setup_packet(struct cli_state *cli);
+void cli_setup_bcc(struct cli_state *cli, void *p);
+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_connection(struct cli_state *cli);
+void cli_shutdown(struct cli_state *cli);
+void cli_sockopt(struct cli_state *cli, char *options);
+uint16 cli_setpid(struct cli_state *cli, uint16 pid);
+BOOL cli_send_keepalive(struct cli_state *cli);
+
+/* The following definitions come from libsmb/clierror.c */
+
+const char *cli_errstr(struct cli_state *cli);
+NTSTATUS cli_nt_error(struct cli_state *cli);
+void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode);
+int cli_errno_from_dos(uint8 eclass, uint32 num);
+int cli_errno_from_nt(NTSTATUS status);
+int cli_errno(struct cli_state *cli);
+BOOL cli_is_error(struct cli_state *cli);
+BOOL cli_is_nt_error(struct cli_state *cli);
+BOOL cli_is_dos_error(struct cli_state *cli);
+
+/* The following definitions come from libsmb/clifile.c */
+
+uint32 unix_perms_to_wire(mode_t perms);
+BOOL cli_unix_symlink(struct cli_state *cli, const char *fname_src, const char *fname_dst);
+BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst);
+BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode);
+BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid);
+BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst);
+BOOL cli_unlink(struct cli_state *cli, const char *fname);
+BOOL cli_mkdir(struct cli_state *cli, const char *dname);
+BOOL cli_rmdir(struct cli_state *cli, const char *dname);
+int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag);
+int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess,
+ uint32 FileAttributes, uint32 ShareAccess,
+ uint32 CreateDisposition, uint32 CreateOptions);
+int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess);
+int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode);
+BOOL cli_close(struct cli_state *cli, int fnum);
+NTSTATUS cli_locktype(struct cli_state *cli, int fnum,
+ uint32 offset, uint32 len, int timeout, unsigned char locktype);
+BOOL cli_lock(struct cli_state *cli, int fnum,
+ uint32 offset, uint32 len, int timeout, enum brl_type lock_type);
+BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len);
+BOOL cli_lock64(struct cli_state *cli, int fnum,
+ SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type);
+BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len);
+BOOL cli_getattrE(struct cli_state *cli, int fd,
+ uint16 *attr, SMB_BIG_UINT *size,
+ time_t *c_time, time_t *a_time, time_t *m_time);
+BOOL cli_getatr(struct cli_state *cli, const char *fname,
+ uint16 *attr, size_t *size, time_t *t);
+BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t);
+BOOL cli_chkpath(struct cli_state *cli, const char *path);
+BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
+int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path);
+
+/* The following definitions come from libsmb/clilist.c */
+
+int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
+ void (*fn)(file_info *, const char *, void *), void *state);
+int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
+ void (*fn)(file_info *, const char *, void *), void *state);
+int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
+ void (*fn)(file_info *, const char *, void *), void *state);
+
+/* The following definitions come from libsmb/cli_lsarpc.c */
+
+struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL sec_qos, uint32 des_access, POLICY_HND *pol);
+NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL sec_qos, uint32 des_access, POLICY_HND *pol);
+NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol);
+NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, int num_sids, DOM_SID *sids,
+ char ***domains, char ***names, uint32 **types);
+NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, int num_names,
+ const char **names, DOM_SID **sids,
+ uint32 **types);
+NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint16 info_class,
+ fstring domain_name, DOM_SID *domain_sid);
+NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_ctx,
+ uint32 *num_domains, char ***domain_names,
+ DOM_SID **domain_sids);
+NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
+ uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low);
+NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char *name, uint16 lang_id, uint16 lang_id_sys,
+ fstring description, uint16 *lang_id_desc);
+NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length,
+ uint32 *num_sids, DOM_SID **sids);
+NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access,
+ POLICY_HND *user_pol);
+NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *count, LUID_ATTR **set);
+NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char *name, LUID *luid);
+NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 sec_info,
+ SEC_DESC_BUF **psdb);
+BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid);
+
+/* The following definitions come from libsmb/climessage.c */
+
+BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
+ int *grp);
+BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp);
+BOOL cli_message_end(struct cli_state *cli, int grp);
+
+/* The following definitions come from libsmb/cli_netlogon.c */
+
+struct cli_state *cli_netlogon_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal,
+ DOM_CHAL *srv_chal);
+NTSTATUS new_cli_net_auth2(struct cli_state *cli,
+ uint16 sec_chan,
+ uint32 neg_flags, DOM_CHAL *srv_chal);
+NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli,
+ uint16 sec_chan,
+ const unsigned char mach_pwd[16]);
+NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 query_level);
+NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds,
+ uint32 database_id, uint32 *num_deltas,
+ SAM_DELTA_HDR **hdr_deltas,
+ SAM_DELTA_CTR **deltas);
+NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 database_id, UINT64_S seqnum,
+ uint32 *num_deltas,
+ SAM_DELTA_HDR **hdr_deltas,
+ SAM_DELTA_CTR **deltas);
+NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ const char *unix_username, const char *unix_password,
+ int logon_type);
+NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ const char *unix_username, const char *unix_domain, const char *workstation,
+ const uint8 chal[8],
+ DATA_BLOB lm_response, DATA_BLOB nt_response,
+ NET_USER_INFO_3 *info3);
+
+/* The following definitions come from libsmb/clioplock.c */
+
+BOOL cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level);
+void cli_oplock_handler(struct cli_state *cli,
+ BOOL (*handler)(struct cli_state *, int, unsigned char));
+
+/* The following definitions come from libsmb/cli_pipe_util.c */
+
+struct cli_state *cli_pipe_initialise(struct cli_state *cli, char *system_name,
+ const char *pipe_name,
+ struct ntuser_creds *creds);
+void cli_pipe_shutdown(struct cli_state *cli);
+
+/* The following definitions come from libsmb/cliprint.c */
+
+int cli_print_queue(struct cli_state *cli,
+ void (*fn)(struct print_job_info *));
+int cli_printjob_del(struct cli_state *cli, int job);
+
+/* The following definitions come from libsmb/clirap.c */
+
+BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name,
+ uint16 *setup, uint32 setup_count, uint32 max_setup_count,
+ char *params, uint32 param_count, uint32 max_param_count,
+ char *data, uint32 data_count, uint32 max_data_count,
+ char **rparam, uint32 *rparam_count,
+ char **rdata, uint32 *rdata_count);
+BOOL cli_api(struct cli_state *cli,
+ char *param, int prcnt, int mprcnt,
+ char *data, int drcnt, int mdrcnt,
+ char **rparam, unsigned int *rprcnt,
+ char **rdata, unsigned int *rdrcnt);
+BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
+int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state);
+BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
+ void (*fn)(const char *, uint32, const char *, void *),
+ void *state);
+BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
+ const char *old_password);
+BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ size_t *size, uint16 *mode);
+BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, size_t *size, uint16 *mode,
+ SMB_INO_T *ino);
+BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
+ uint16 *mode, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, SMB_INO_T *ino);
+BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata);
+NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name);
+
+/* The following definitions come from libsmb/clireadwrite.c */
+
+ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
+ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
+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);
+
+/* The following definitions come from libsmb/cli_reg.c */
+
+struct cli_state *cli_winreg_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+ const char *msg, uint32 timeout, uint16 flags);
+NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx);
+
+/* The following definitions come from libsmb/cli_samr.c */
+
+struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 access_mask, POLICY_HND *connect_pol);
+NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *connect_pol);
+NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *connect_pol, uint32 access_mask,
+ DOM_SID *domain_sid, POLICY_HND *domain_pol);
+NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 user_rid, POLICY_HND *user_pol);
+NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 group_rid, POLICY_HND *group_pol);
+NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ SAM_USERINFO_CTR **ctr);
+NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *group_pol, uint32 info_level,
+ GROUP_INFO_CTR **ctr);
+NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint32 *num_groups,
+ DOM_GID **gid);
+NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **als_rids);
+NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *group_pol, uint32 *num_mem,
+ uint32 **rid, uint32 **attr);
+NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *start_idx,
+ uint32 size, struct acct_info **dom_groups,
+ uint32 *num_dom_groups);
+NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *start_idx,
+ uint32 size, struct acct_info **dom_groups,
+ uint32 *num_dom_groups);
+NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *alias_pol, uint32 *num_mem,
+ DOM_SID **sids);
+NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 alias_rid, POLICY_HND *alias_pol);
+NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint16 switch_value,
+ SAM_UNK_CTR *ctr);
+void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
+ uint32 *max_size);
+NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 *start_idx,
+ uint16 switch_value, uint32 *num_entries,
+ uint32 max_entries, uint32 max_size,
+ SAM_DISPINFO_CTR *ctr);
+NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_rids, uint32 *rids,
+ uint32 *num_names, char ***names,
+ uint32 **name_types);
+NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_names, const char **names,
+ uint32 *num_rids, uint32 **rids,
+ uint32 **rid_types);
+NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, char *acct_name,
+ uint32 acb_info, uint32 unknown,
+ POLICY_HND *user_pol, uint32 *rid);
+NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr);
+NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr);
+NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol);
+NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf);
+
+/* The following definitions come from libsmb/clisecdesc.c */
+
+SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
+ TALLOC_CTX *mem_ctx);
+BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd);
+
+/* The following definitions come from libsmb/cli_spoolss.c */
+
+struct cli_state *cli_spoolss_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds);
+WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *printername, const char *datatype, uint32 access_required,
+ char *station, char *username, POLICY_HND *pol);
+WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol);
+WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ uint32 flags, uint32 level,
+ uint32 *num_printers, PRINTER_INFO_CTR *ctr);
+WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ uint32 level, int *num_ports, PORT_INFO_CTR *ctr);
+WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ POLICY_HND *pol, uint32 level,
+ PRINTER_INFO_CTR *ctr);
+WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 level,
+ PRINTER_INFO_CTR *ctr, uint32 command);
+WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ POLICY_HND *pol, uint32 level,
+ const char *env, PRINTER_DRIVER_CTR *ctr);
+WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ uint32 level, const char *env,
+ uint32 *num_drivers,
+ PRINTER_DRIVER_CTR *ctr);
+WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ uint32 level, char *env,
+ DRIVER_DIRECTORY_CTR *ctr);
+WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, uint32 level,
+ PRINTER_DRIVER_CTR *ctr);
+WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 level, PRINTER_INFO_CTR*ctr);
+WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, const char *arch,
+ char *driver);
+WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ char *name, char *environment,
+ fstring procdir);
+WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle, uint32 level, FORM *form);
+WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle, uint32 level, char *form_name,
+ FORM *form);
+WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ POLICY_HND *handle, char *formname, uint32 level,
+ FORM_1 *form);
+WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle, char *form_name);
+WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ POLICY_HND *handle, int level, uint32 *num_forms,
+ FORM_1 **forms);
+WERROR cli_spoolss_setprinterdata (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char* valname, char* value);
+
+/* The following definitions come from libsmb/cli_srvsvc.c */
+
+struct cli_state *cli_svrsvc_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 switch_value, SRV_INFO_CTR *ctr);
+
+/* The following definitions come from libsmb/clistr.c */
+
+int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags);
+int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags);
+int clistr_align_out(struct cli_state *cli, const void *p, int flags);
+int clistr_align_in(struct cli_state *cli, const void *p, int flags);
+
+/* The following definitions come from libsmb/clitrans.c */
+
+BOOL cli_send_trans(struct cli_state *cli, int trans,
+ const char *pipe_name,
+ int fid, int flags,
+ uint16 *setup, unsigned int lsetup, unsigned int msetup,
+ char *param, unsigned int lparam, unsigned int mparam,
+ char *data, unsigned int ldata, unsigned int mdata);
+BOOL cli_receive_trans(struct cli_state *cli,int trans,
+ char **param, unsigned int *param_len,
+ char **data, unsigned int *data_len);
+BOOL cli_send_nt_trans(struct cli_state *cli,
+ int function,
+ int flags,
+ uint16 *setup, unsigned int lsetup, unsigned int msetup,
+ char *param, unsigned int lparam, unsigned int mparam,
+ char *data, unsigned int ldata, unsigned int mdata);
+BOOL cli_receive_nt_trans(struct cli_state *cli,
+ char **param, unsigned int *param_len,
+ char **data, unsigned int *data_len);
+
+/* The following definitions come from libsmb/credentials.c */
+
+char *credstr(const uchar *cred);
+void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass,
+ uchar session_key[8]);
+void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp,
+ DOM_CHAL *cred);
+int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
+ UTIME timestamp);
+BOOL clnt_deal_with_creds(uchar sess_key[8],
+ DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred);
+BOOL deal_with_creds(uchar sess_key[8],
+ DOM_CRED *sto_clnt_cred,
+ DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred);
+
+/* The following definitions come from libsmb/doserr.c */
+
+const char *dos_errstr(WERROR werror);
+
+/* The following definitions come from libsmb/errormap.c */
+
+NTSTATUS dos_to_ntstatus(int eclass, int ecode);
+void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode);
+NTSTATUS werror_to_ntstatus(WERROR error);
+WERROR ntstatus_to_werror(NTSTATUS error);
+
+/* The following definitions come from libsmb/namecache.c */
+
+BOOL namecache_enable(void);
+void namecache_store(const char *name, int name_type,
+ int num_names, struct in_addr *ip_list);
+BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list,
+ int *num_names);
+void namecache_flush(void);
+
+/* The following definitions come from libsmb/namequery.c */
+
+struct node_status *node_status_query(int fd,struct nmb_name *name,
+ struct in_addr to_ip, int *num_names);
+BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name);
+BOOL name_register(int fd, const char *name, int name_type,
+ struct in_addr name_ip, int opcode,
+ BOOL bcast,
+ struct in_addr to_ip, int *count);
+struct in_addr *name_query(int fd,const char *name,int name_type,
+ BOOL bcast,BOOL recurse,
+ struct in_addr to_ip, int *count, int *flags);
+FILE *startlmhosts(const char *fname);
+BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr);
+void endlmhosts(FILE *fp);
+BOOL name_register_wins(const char *name, int name_type);
+BOOL name_resolve_bcast(const char *name, int name_type,
+ struct in_addr **return_ip_list, int *return_count);
+BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type);
+BOOL resolve_name_2(const char *name, struct in_addr **return_ip, int *count, 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_dc_name(const char *srcname, const char *domain,
+ struct in_addr *dc_ip, char *ret_name);
+BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count);
+BOOL get_lmb_list(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);
+struct packet_struct *copy_packet(struct packet_struct *packet);
+void free_packet(struct packet_struct *packet);
+struct packet_struct *parse_packet(char *buf,int length,
+ enum packet_type packet_type);
+struct packet_struct *read_packet(int fd,enum packet_type packet_type);
+void make_nmb_name( struct nmb_name *n, const char *name, int type);
+BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
+int build_packet(char *buf, struct packet_struct *p);
+BOOL send_packet(struct packet_struct *p);
+struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
+struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id);
+struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name);
+BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name);
+void sort_query_replies(char *data, int n, struct in_addr ip);
+char *dns_to_netbios_name(char *dns_name);
+int name_mangle( char *In, char *Out, char name_type );
+int name_extract(char *buf,int ofs,char *name);
+int name_len(char *s1);
+
+/* The following definitions come from libsmb/nterr.c */
+
+const char *get_nt_error_msg(NTSTATUS nt_code);
+const char *nt_errstr(NTSTATUS nt_code);
+const char *get_nt_error_c_code(NTSTATUS nt_code);
+
+/* The following definitions come from libsmb/passchange.c */
+
+BOOL remote_password_change(const char *remote_machine, const char *user_name,
+ const char *old_passwd, const char *new_passwd,
+ char *err_str, size_t err_str_len);
+
+/* 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);
+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, const 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(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_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[24]);
+
+/* The following definitions come from lib/smbrun.c */
+
+int smbrun(char *cmd, int *outfd);
+
+/* The following definitions come from libsmb/smbdes.c */
+
+void E_P16(const unsigned char *p14,unsigned char *p16);
+void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24);
+void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out);
+void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out);
+void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char *key);
+void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key);
+void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, int forw);
+void SamOEMhash( unsigned char *data, const unsigned char *key, int val);
+void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw);
+
+/* The following definitions come from libsmb/smbencrypt.c */
+
+void SMBencrypt(const uchar *passwd, uchar *c8, uchar *p24);
+void E_md4hash(const 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(const uchar *passwd, uchar *c8, uchar *p24);
+BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode);
+BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
+ int new_pw_len, BOOL nt_pass_set);
+BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
+ int new_pwrd_size, uint32 *new_pw_len,
+ uchar nt_p16[16], uchar p16[16]);
+void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]);
+
+/* The following definitions come from libsmb/smberr.c */
+
+const char *smb_dos_err_name(uint8 class, uint16 num);
+const char *get_dos_error_msg(WERROR result);
+const char *smb_dos_err_class(uint8 class);
+const char *smb_dos_errstr(char *inbuf);
+WERROR map_werror_from_unix(int error);
+
+/* The following definitions come from libsmb/unexpected.c */
+
+void unexpected_packet(struct packet_struct *p);
+void clear_unexpected(time_t t);
+struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
+ const char *mailslot_name);
+
+/* The following definitions come from lib/snprintf.c */
+
+
+/* The following definitions come from lib/substitute.c */
+
+void sub_set_smb_name(const char *name);
+const char* get_remote_machine_name(void);
+void standard_sub_basic(char *str, int len);
+void standard_sub_advanced(int snum, char *user, const char *connectpath, gid_t gid, char *str, int len);
+void standard_sub_conn(connection_struct *conn, char *str, int len);
+void standard_sub_home(int snum, char *user, char *str, int len);
+void standard_sub_snum(int snum, char *str, int len);
+void standard_sub_vuser(char *str, int len, user_struct *vuser);
+void standard_sub_vsnum(char *str, int len, user_struct *vuser, int snum);
+
+/* The following definitions come from lib/sysacls.c */
+
+int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
+int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T sys_acl_get_fd(int fd);
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
+int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen);
+SMB_ACL_T sys_acl_init( int count);
+int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
+int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
+int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual);
+int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
+int sys_acl_valid( SMB_ACL_T theacl );
+int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+int sys_acl_set_fd( int fd, SMB_ACL_T theacl);
+int sys_acl_delete_def_file(const char *name);
+int sys_acl_free_text(char *text);
+int sys_acl_free_acl(SMB_ACL_T the_acl) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
+int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T sys_acl_get_fd(int fd);
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
+int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen);
+SMB_ACL_T sys_acl_init( int count);
+int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
+int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
+int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual);
+int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
+int sys_acl_valid( SMB_ACL_T theacl );
+int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+int sys_acl_set_fd( int fd, SMB_ACL_T theacl);
+int sys_acl_delete_def_file(const char *name);
+int sys_acl_free_text(char *text);
+int sys_acl_free_acl(SMB_ACL_T the_acl) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p);
+int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T sys_acl_get_fd(int fd);
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d);
+int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm);
+int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm);
+char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p);
+SMB_ACL_T sys_acl_init(int count);
+int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type);
+int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p);
+int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d);
+int sys_acl_valid(SMB_ACL_T acl_d);
+int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d);
+int sys_acl_set_fd(int fd, SMB_ACL_T acl_d);
+int sys_acl_delete_def_file(const char *path);
+int sys_acl_free_text(char *text);
+int sys_acl_free_acl(SMB_ACL_T acl_d) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p);
+int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T sys_acl_get_fd(int fd);
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d);
+int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm);
+int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm);
+char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p);
+SMB_ACL_T sys_acl_init(int count);
+int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type);
+int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p);
+int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d);
+int sys_acl_valid(SMB_ACL_T acl_d);
+int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d);
+int sys_acl_set_fd(int fd, SMB_ACL_T acl_d);
+int sys_acl_delete_def_file(const char *path);
+int sys_acl_free_text(char *text);
+int sys_acl_free_acl(SMB_ACL_T acl_d) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p);
+int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T sys_acl_get_fd(int fd);
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d);
+int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm);
+int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm);
+char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p);
+SMB_ACL_T sys_acl_init(int count);
+int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type);
+int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p);
+int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d);
+int sys_acl_valid(SMB_ACL_T acl_d);
+int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d);
+int sys_acl_set_fd(int fd, SMB_ACL_T acl_d);
+int sys_acl_delete_def_file(const char *name);
+int sys_acl_free_text(char *text);
+int sys_acl_free_acl(SMB_ACL_T acl_d) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
+int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T sys_acl_get_fd(int fd);
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
+int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen);
+SMB_ACL_T sys_acl_init( int count);
+int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
+int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
+int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual);
+int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
+int sys_acl_valid( SMB_ACL_T theacl );
+int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+int sys_acl_set_fd( int fd, SMB_ACL_T theacl);
+int sys_acl_delete_def_file(const char *name);
+int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+int sys_acl_free_text(char *text);
+int sys_acl_free_acl(SMB_ACL_T posix_acl);
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
+int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T sys_acl_get_fd(int fd);
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
+int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen);
+int sys_acl_free_text(char *text);
+SMB_ACL_T sys_acl_init( int count);
+int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
+int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
+int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual);
+int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
+int sys_acl_valid( SMB_ACL_T theacl );
+int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+int sys_acl_set_fd( int fd, SMB_ACL_T theacl);
+int sys_acl_delete_def_file(const char *name);
+int sys_acl_free_acl(SMB_ACL_T the_acl) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+
+/* The following definitions come from lib/system.c */
+
+int sys_usleep(long usecs);
+ssize_t sys_read(int fd, void *buf, size_t count);
+ssize_t sys_write(int fd, const void *buf, size_t count);
+ssize_t sys_send(int s, const void *msg, size_t len, int flags);
+ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
+ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
+int sys_fcntl_ptr(int fd, int cmd, void *arg);
+int sys_fcntl_long(int fd, int cmd, long arg);
+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);
+int sys_ftruncate(int fd, SMB_OFF_T offset);
+SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence);
+int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence);
+SMB_OFF_T sys_ftell(FILE *fp);
+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);
+SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp);
+int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev);
+char *sys_realpath(const char *path, char *resolved_path);
+int sys_waitpid(pid_t pid,int *status,int options);
+char *sys_getwd(char *s);
+int sys_symlink(const char *oldpath, const char *newpath);
+int sys_readlink(const char *path, char *buf, size_t bufsiz);
+int sys_link(const char *oldpath, const char *newpath);
+int sys_chown(const char *fname,uid_t uid,gid_t gid);
+int sys_chroot(const char *dname);
+struct hostent *sys_gethostbyname(const char *name);
+void oplock_set_capability(BOOL this_process, BOOL inherit);
+long sys_random(void);
+void sys_srandom(unsigned int seed);
+int groups_max(void);
+int sys_getgroups(int setlen, gid_t *gidset);
+int sys_setgroups(int setlen, gid_t *gidset);
+void sys_setpwent(void);
+struct passwd *sys_getpwent(void);
+void sys_endpwent(void);
+struct passwd *sys_getpwnam(const char *name);
+struct passwd *sys_getpwuid(uid_t uid);
+int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);
+int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);
+int wsys_creat(const smb_ucs2_t *wfname, mode_t mode);
+int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode);
+FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type);
+DIR *wsys_opendir(const smb_ucs2_t *wfname);
+smb_ucs2_t *wsys_getwd(smb_ucs2_t *s);
+int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid);
+int wsys_chroot(const smb_ucs2_t *wfname);
+pid_t sys_fork(void);
+pid_t sys_getpid(void);
+int sys_popen(const char *command);
+int sys_pclose(int fd);
+void *sys_dlopen(const char *name, int flags);
+void *sys_dlsym(void *handle, const char *symbol);
+int sys_dlclose (void *handle);
+const char *sys_dlerror(void);
+void sys_adminlog(int priority, const char *format_str, ...);
+
+/* The following definitions come from lib/talloc.c */
+
+TALLOC_CTX *talloc_init(void);
+void *talloc(TALLOC_CTX *t, size_t size);
+void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size);
+void talloc_destroy_pool(TALLOC_CTX *t);
+void talloc_destroy(TALLOC_CTX *t);
+size_t talloc_pool_size(TALLOC_CTX *t);
+const char * talloc_pool_name(TALLOC_CTX const *t);
+void *talloc_zero(TALLOC_CTX *t, size_t size);
+void *talloc_memdup(TALLOC_CTX *t, const void *p, size_t size);
+char *talloc_strdup(TALLOC_CTX *t, const char *p);
+char *talloc_describe_all(TALLOC_CTX *rt);
+void talloc_get_allocation(TALLOC_CTX *t,
+ size_t *total_bytes,
+ int *n_chunks);
+
+/* The following definitions come from lib/time.c */
+
+time_t get_time_t_min(void);
+time_t get_time_t_max(void);
+void GetTimeOfDay(struct timeval *tval);
+void TimeInit(void);
+void get_process_uptime(struct timeval *ret_time);
+int TimeDiff(time_t t);
+struct tm *LocalTime(time_t *t);
+time_t nt_time_to_unix(NTTIME *nt);
+time_t nt_time_to_unix_abs(NTTIME *nt);
+time_t interpret_long_date(char *p);
+void unix_to_nt_time(NTTIME *nt, time_t t);
+void unix_to_nt_time_abs(NTTIME *nt, time_t t);
+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);
+void put_dos_date2(char *buf,int offset,time_t unixdate);
+void put_dos_date3(char *buf,int offset,time_t unixdate);
+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(BOOL hires);
+time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs);
+void init_nt_time(NTTIME *nt);
+
+/* The following definitions come from lib/ufc.c */
+
+char *ufc_crypt(const char *key,const char *salt);
+
+/* The following definitions come from lib/username.c */
+
+BOOL name_is_local(const char *name);
+char *get_user_home_dir(char *user);
+char *get_user_service_home_dir(char *user);
+BOOL map_username(char *user);
+struct passwd *Get_Pwnam(char *user,BOOL allow_change);
+BOOL user_in_group_list(char *user,char *gname);
+BOOL user_in_list(char *user,char *list);
+struct passwd *smb_getpwnam(char *user, BOOL allow_change);
+
+/* The following definitions come from lib/util.c */
+
+const char *tmpdir(void);
+BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups);
+const char *Atoic(const char *p, int *n, const char *c);
+const char *get_numlist(const char *p, uint32 **num, int *count);
+BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf);
+time_t file_modtime(const char *fname);
+BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st);
+SMB_OFF_T get_file_size(char *file_name);
+char *attrib_string(uint16 mode);
+void show_msg(char *buf);
+void smb_setlen(char *buf,int len);
+int set_message(char *buf,int num_words,int num_bytes,BOOL zero);
+int set_message_bcc(char *buf,int num_bytes);
+int set_message_end(void *outbuf,void *end_ptr);
+void dos_clean_name(char *s);
+void unix_clean_name(char *s);
+void make_dir_struct(char *buf,const char *mask,const char *fname,SMB_OFF_T size,int mode,time_t date);
+void close_low_fds(void);
+int set_blocking(int fd, BOOL set);
+ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
+ ssize_t (*write_fn)(int, const void *, size_t));
+SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n);
+void msleep(unsigned int t);
+void become_daemon(void);
+BOOL yesno(char *p);
+void *Realloc(void *p,size_t size);
+void safe_free(void *p);
+BOOL get_myname(char *my_name);
+int interpret_protocol(char *str,int def);
+BOOL is_ipaddress(const char *str);
+uint32 interpret_addr(const char *str);
+struct in_addr *interpret_addr2(const char *str);
+BOOL is_zero_ip(struct in_addr ip);
+void zero_ip(struct in_addr *ip);
+char *automount_lookup(char *user_name);
+char *automount_lookup(char *user_name);
+BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
+BOOL process_exists(pid_t pid);
+char *uidtoname(uid_t uid);
+char *gidtoname(gid_t gid);
+uid_t nametouid(char *name);
+gid_t nametogid(char *name);
+void smb_panic(const char *why);
+char *readdirname(DIR *p);
+BOOL is_in_path(const char *name, name_compare_entry *namelist);
+void set_namearray(name_compare_entry **ppname_array, char *namelist);
+void free_namearray(name_compare_entry *name_array);
+BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+BOOL is_myname(char *s);
+const char* get_my_primary_ip (void);
+BOOL is_myname_or_ipaddr(char *s);
+void set_remote_arch(enum remote_arch_types type);
+enum remote_arch_types get_remote_arch(void);
+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);
+BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name);
+int smb_mkstemp(char *template);
+void *smb_xmalloc(size_t size);
+void *smb_xmemdup(const void *p, size_t size);
+char *smb_xstrdup(const char *s);
+int smb_xvasprintf(char **ptr, const char *format, va_list ap);
+void *memdup(void *p, size_t size);
+char *myhostname(void);
+char *lock_path(const char *name);
+char *pid_path(char *name);
+char *parent_dirname(const char *path);
+BOOL ms_has_wild(char *s);
+BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive);
+BOOL unix_wild_match(char *pattern, char *string);
+DATA_BLOB data_blob(const void *p, size_t length);
+DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length);
+void data_blob_free(DATA_BLOB *d);
+void data_blob_clear(DATA_BLOB *d);
+int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6);
+
+/* 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 *startfilepwent(char *pfile, char *s_readbuf, int bufsize,
+ int *file_lock_depth, BOOL update);
+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);
+char *file_pload(const char *syscmd, size_t *size);
+char *fd_load(int fd, size_t *size);
+char *file_load(const char *fname, size_t *size);
+char **file_lines_load(const char *fname, int *numlines, BOOL convert);
+char **fd_lines_load(int fd, int *numlines, BOOL convert);
+char **file_lines_pload(const char *syscmd, int *numlines, BOOL convert);
+void file_lines_free(char **lines);
+void file_lines_slashcont(char **lines);
+
+/* The following definitions come from lib/util_getent.c */
+
+struct sys_grent * getgrent_list(void);
+void grent_free (struct sys_grent *glist);
+struct sys_pwent * getpwent_list(void);
+void pwent_free (struct sys_pwent *plist);
+struct sys_userlist *get_users_in_group(const char *gname);
+void free_userlist(struct sys_userlist *list_head);
+
+/* The following definitions come from lib/util_seaccess.c */
+
+void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping);
+void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping);
+BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
+ uint32 acc_desired, uint32 *acc_granted,
+ NTSTATUS *status);
+SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
+ BOOL child_container);
+
+/* The following definitions come from lib/util_sec.c */
+
+void sec_init(void);
+uid_t sec_initial_uid(void);
+gid_t sec_initial_gid(void);
+BOOL non_root_mode(void);
+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);
+void save_re_gid(void);
+void restore_re_gid(void);
+int set_re_uid(void);
+void become_user_permanently(uid_t uid, gid_t gid);
+BOOL is_setuid_root(void) ;
+
+/* The following definitions come from lib/util_sid.c */
+
+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, enum SID_NAME_USE *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, const DOM_SID *sid);
+const char *sid_string_static(const DOM_SID *sid);
+BOOL string_to_sid(DOM_SID *sidout, const char *sidstr);
+BOOL sid_append_rid(DOM_SID *sid, uint32 rid);
+BOOL sid_split_rid(DOM_SID *sid, uint32 *rid);
+BOOL sid_peek_rid(DOM_SID *sid, uint32 *rid);
+void sid_copy(DOM_SID *dst, const DOM_SID *src);
+DOM_SID *sid_dup(DOM_SID *src);
+BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid);
+BOOL sid_parse(char *inbuf, size_t len, DOM_SID *sid);
+int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2);
+int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2);
+int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2);
+BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2);
+BOOL sid_check_is_domain(const DOM_SID *sid);
+BOOL sid_check_is_builtin(const DOM_SID *sid);
+BOOL sid_check_is_in_our_domain(const DOM_SID *sid);
+BOOL sid_check_is_in_builtin(const DOM_SID *sid);
+size_t sid_size(DOM_SID *sid);
+BOOL non_mappable_sid(DOM_SID *sid);
+char *sid_binstring(DOM_SID *sid);
+
+/* The following definitions come from lib/util_sock.c */
+
+BOOL is_a_socket(int fd);
+void set_socket_options(int fd, const char *options);
+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_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, BOOL rebind );
+int open_socket_out(int type, struct in_addr *addr, int port ,int timeout);
+void client_setfd(int fd);
+char *client_name(void);
+char *client_addr(void);
+char *get_socket_name(int fd);
+char *get_socket_addr(int fd);
+int create_pipe_sock(const char *socket_dir,
+ const char *socket_name,
+ mode_t dir_perms);
+int sock_exec(const char *prog);
+
+/* The following definitions come from lib/util_str.c */
+
+void set_first_token(char *ptr);
+BOOL next_token(const char **ptr,char *buff,const char *sep, size_t bufsize);
+char **toktocliplist(int *ctok, const char *sep);
+int StrCaseCmp(const char *s, const char *t);
+int StrnCaseCmp(const char *s, const char *t, size_t n);
+BOOL strequal(const char *s1, const char *s2);
+BOOL strequal_unix(const char *s1, const char *s2);
+BOOL strnequal(const char *s1,const char *s2,size_t n);
+BOOL strcsequal(const char *s1,const char *s2);
+int strwicmp(const char *psz1, const char *psz2);
+void strlower(char *s);
+void strupper(char *s);
+char *strupper_static(const char *s);
+void strnorm(char *s);
+BOOL strisnormal(char *s);
+void string_replace(char *s,char oldc,char newc);
+char *skip_string(char *buf,size_t n);
+size_t str_charnum(const char *s);
+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 *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength);
+char *StrnCpy(char *dest,const char *src,size_t n);
+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);
+void string_free(char **s);
+BOOL string_set(char **dest,const char *src);
+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);
+const char *octal_string(int i);
+char *string_truncate(char *s, int length);
+char *binary_string(char *buf, int len);
+
+/* The following definitions come from lib/util_unistr.c */
+
+size_t unix_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate);
+size_t dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate);
+void unistr_to_dos(char *dest, const char *src, size_t len);
+char *skip_unibuf(char *src, size_t len);
+char *dos_unistrn2(uint16 *src, int len);
+char *dos_unistr2(uint16 *src);
+char *dos_unistr2_to_str(UNISTR2 *str);
+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_dos(char *dest, const UNISTR2 *str, size_t maxlen);
+void unistr2_to_unix(char *dest, const UNISTR2 *str, size_t maxlen);
+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 unistrlen(uint16 *s);
+int unistrcpy(uint16 *dst, uint16 *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, BOOL override);
+smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
+ size_t dst_len, smb_ucs2_t *cp_to_ucs2);
+char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len);
+smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
+size_t unicode_to_unix_char(char *dst, const smb_ucs2_t src);
+char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len);
+size_t unicode_to_dos_char(char *dst, const smb_ucs2_t src);
+smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
+size_t strlen_w(const smb_ucs2_t *src);
+smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength);
+smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength);
+int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
+int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len);
+smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
+smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
+smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
+smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2);
+smb_ucs2_t *strdup_w(const smb_ucs2_t *s);
+int isupper_w( smb_ucs2_t val);
+int islower_w( smb_ucs2_t val);
+int isdigit_w( smb_ucs2_t val);
+int isxdigit_w( smb_ucs2_t val);
+int isspace_w( smb_ucs2_t val);
+smb_ucs2_t toupper_w( smb_ucs2_t val );
+smb_ucs2_t tolower_w( smb_ucs2_t val );
+void set_first_token_w(smb_ucs2_t *ptr);
+BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize);
+smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep);
+int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t);
+int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n);
+BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
+BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n);
+BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2);
+void strlower_w(smb_ucs2_t *s);
+void strupper_w(smb_ucs2_t *s);
+void strnorm_w(smb_ucs2_t *s);
+BOOL strisnormal_w(smb_ucs2_t *s);
+void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc);
+smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n);
+size_t str_charnum_w(const smb_ucs2_t *s);
+BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back);
+BOOL strhasupper_w(const smb_ucs2_t *s);
+BOOL strhaslower_w(const smb_ucs2_t *s);
+size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c);
+BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c);
+smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, const smb_ucs2_t *other_safe_chars, size_t maxlength);
+smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n);
+smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c);
+size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex);
+BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive);
+BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src);
+void string_free_w(smb_ucs2_t **s);
+BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src);
+void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len);
+void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert);
+void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert);
+void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len);
+void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back);
+smb_ucs2_t *octal_string_w(int i);
+smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length);
+smb_ucs2_t doscp2ucs2(int w);
+int ucs2doscp(smb_ucs2_t w);
+int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags);
+
+/* The following definitions come from lib/wins_srv.c */
+
+BOOL wins_srv_load_list( const char *src );
+struct in_addr wins_srv_ip( void );
+void wins_srv_died( struct in_addr boothill_ip );
+unsigned long wins_srv_count( void );
+
+/* The following definitions come from locking/brlock.c */
+
+void brl_init(int read_only);
+void brl_shutdown(int read_only);
+NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
+ uint16 smbpid, pid_t pid, uint16 tid,
+ br_off start, br_off size,
+ enum brl_type lock_type);
+BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
+ uint16 smbpid, pid_t pid, uint16 tid,
+ br_off start, br_off size,
+ BOOL remove_pending_locks_only);
+BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
+ uint16 smbpid, pid_t pid, uint16 tid,
+ br_off start, br_off size,
+ enum brl_type lock_type, int check_self);
+void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum);
+int brl_forall(BRLOCK_FN(fn));
+
+/* The following definitions come from locking/locking.c */
+
+BOOL is_locked(files_struct *fsp,connection_struct *conn,
+ SMB_BIG_UINT count,SMB_BIG_UINT offset,
+ enum brl_type lock_type, BOOL check_self);
+NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
+ SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type);
+NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
+ SMB_BIG_UINT count,SMB_BIG_UINT offset);
+void locking_close_file(files_struct *fsp);
+BOOL locking_init(int read_only);
+BOOL locking_end(void);
+BOOL lock_share_entry(connection_struct *conn,
+ SMB_DEV_T dev, SMB_INO_T inode);
+void unlock_share_entry(connection_struct *conn,
+ SMB_DEV_T dev, SMB_INO_T inode);
+BOOL lock_share_entry_fsp(files_struct *fsp);
+void unlock_share_entry_fsp(files_struct *fsp);
+int get_share_modes(connection_struct *conn,
+ SMB_DEV_T dev, SMB_INO_T inode,
+ share_mode_entry **pp_shares);
+BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2);
+ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
+ share_mode_entry *entry, share_mode_entry **ppse);
+ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse);
+BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type);
+BOOL remove_share_oplock(files_struct *fsp);
+BOOL downgrade_share_oplock(files_struct *fsp);
+BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close);
+int share_mode_forall(SHAREMODE_FN(fn));
+
+/* The following definitions come from locking/posix.c */
+
+int fd_close_posix(struct connection_struct *conn, files_struct *fsp);
+BOOL is_posix_locked(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type);
+BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type);
+BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count);
+void posix_locking_close_file(files_struct *fsp);
+BOOL posix_locking_init(int read_only);
+BOOL posix_locking_end(void);
+
+/* The following definitions come from msdfs/msdfs.c */
+
+BOOL is_msdfs_link(connection_struct* conn, char* path,
+ struct referral** reflistp, int* refcnt,
+ SMB_STRUCT_STAT *sbufp);
+BOOL dfs_redirect(char* pathname, connection_struct* conn,
+ BOOL findfirst_flag);
+BOOL get_referred_path(char *pathname, struct junction_map* jn,
+ int* consumedcntp, BOOL* self_referralp);
+int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata);
+int dfs_path_error(char* inbuf, char* outbuf);
+BOOL create_junction(char* pathname, struct junction_map* jn);
+BOOL create_msdfs_link(struct junction_map* jn, BOOL exists);
+BOOL remove_msdfs_link(struct junction_map* jn);
+int enum_msdfs_links(struct junction_map* jn);
+
+/* The following definitions come from nmbd/asyncdns.c */
+
+int asyncdns_fd(void);
+void kill_async_dns_child(void);
+void start_async_dns(void);
+void run_dns_queue(void);
+BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
+ struct name_record **n);
+BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
+ struct name_record **n);
+void kill_async_dns_child(void);
+
+/* The following definitions come from nmbd/nmbd_become_dmb.c */
+
+void add_domain_names(time_t t);
+
+/* The following definitions come from nmbd/nmbd_become_lmb.c */
+
+void insert_permanent_name_into_unicast( struct subnet_record *subrec,
+ struct nmb_name *nmbname, uint16 nb_type );
+void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
+ BOOL force_new_election);
+void become_local_master_browser(struct subnet_record *subrec, struct work_record *work);
+void set_workgroup_local_master_browser_name( struct work_record *work, const char *newname);
+
+/* The following definitions come from nmbd/nmbd_browserdb.c */
+
+void update_browser_death_time( struct browse_cache_record *browc );
+struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
+ char *browser_name,
+ struct in_addr ip );
+struct browse_cache_record *find_browser_in_lmb_cache( char *browser_name );
+void expire_lmb_browsers( time_t t );
+
+/* The following definitions come from nmbd/nmbd_browsesync.c */
+
+void dmb_expire_and_sync_browser_lists(time_t t);
+void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec,
+ struct work_record *work);
+void collect_all_workgroup_names_from_wins_server(time_t t);
+void sync_all_dmbs(time_t t);
+
+/* The following definitions come from nmbd/nmbd.c */
+
+
+/* The following definitions come from nmbd/nmbd_elections.c */
+
+void check_master_browser_exists(time_t t);
+void run_elections(time_t t);
+void process_election(struct subnet_record *subrec, struct packet_struct *p, char *buf);
+BOOL check_elections(void);
+void nmbd_message_election(int msg_type, pid_t src, void *buf, size_t len);
+
+/* The following definitions come from nmbd/nmbd_incomingdgrams.c */
+
+void tell_become_backup(void);
+void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf);
+void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf);
+void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf);
+void process_master_browser_announce(struct subnet_record *subrec,
+ struct packet_struct *p,char *buf);
+void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf);
+void process_get_backup_list_request(struct subnet_record *subrec,
+ struct packet_struct *p,char *buf);
+void process_reset_browser(struct subnet_record *subrec,
+ struct packet_struct *p,char *buf);
+void process_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf);
+void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf);
+
+/* The following definitions come from nmbd/nmbd_incomingrequests.c */
+
+void process_name_release_request(struct subnet_record *subrec,
+ struct packet_struct *p);
+void process_name_refresh_request(struct subnet_record *subrec,
+ struct packet_struct *p);
+void process_name_registration_request(struct subnet_record *subrec,
+ struct packet_struct *p);
+void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p);
+void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p);
+
+/* The following definitions come from nmbd/nmbd_lmhosts.c */
+
+void load_lmhosts_file(char *fname);
+BOOL find_name_in_lmhosts(struct nmb_name *nmbname, struct name_record **namerecp);
+
+/* The following definitions come from nmbd/nmbd_logonnames.c */
+
+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);
+
+/* The following definitions come from nmbd/nmbd_namelistdb.c */
+
+void set_samba_nb_type(void);
+void remove_name_from_namelist( struct subnet_record *subrec,
+ struct name_record *namerec );
+struct name_record *find_name_on_subnet( struct subnet_record *subrec,
+ struct nmb_name *nmbname,
+ BOOL self_only );
+struct name_record *find_name_for_remote_broadcast_subnet(
+ struct nmb_name *nmbname,
+ BOOL self_only );
+void update_name_ttl( struct name_record *namerec, int ttl );
+struct name_record *add_name_to_subnet( struct subnet_record *subrec,
+ const char *name,
+ int type,
+ uint16 nb_flags,
+ int ttl,
+ enum name_source source,
+ int num_ips,
+ struct in_addr *iplist);
+void standard_success_register(struct subnet_record *subrec,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname, uint16 nb_flags, int ttl,
+ struct in_addr registered_ip);
+void standard_fail_register( struct subnet_record *subrec,
+ struct response_record *rrec,
+ struct nmb_name *nmbname );
+BOOL find_ip_in_name_record( struct name_record *namerec, struct in_addr ip );
+void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip );
+void remove_ip_from_name_record( struct name_record *namerec,
+ struct in_addr remove_ip );
+void standard_success_release( struct subnet_record *subrec,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ struct in_addr released_ip );
+void expire_names_on_subnet(struct subnet_record *subrec, time_t t);
+void expire_names(time_t t);
+void add_samba_names_to_subnet( struct subnet_record *subrec );
+void dump_all_namelists(void);
+
+/* The following definitions come from nmbd/nmbd_namequery.c */
+
+BOOL query_name(struct subnet_record *subrec, char *name, int type,
+ query_name_success_function success_fn,
+ query_name_fail_function fail_fn,
+ struct userdata_struct *userdata);
+BOOL query_name_from_wins_server(struct in_addr ip_to,
+ char *name, int type,
+ query_name_success_function success_fn,
+ query_name_fail_function fail_fn,
+ struct userdata_struct *userdata);
+
+/* The following definitions come from nmbd/nmbd_nameregister.c */
+
+BOOL register_name(struct subnet_record *subrec,
+ const char *name, int type, uint16 nb_flags,
+ register_name_success_function success_fn,
+ register_name_fail_function fail_fn,
+ struct userdata_struct *userdata);
+BOOL refresh_name(struct subnet_record *subrec, struct name_record *namerec,
+ refresh_name_success_function success_fn,
+ refresh_name_fail_function fail_fn,
+ struct userdata_struct *userdata);
+
+/* The following definitions come from nmbd/nmbd_namerelease.c */
+
+BOOL release_name(struct subnet_record *subrec, struct name_record *namerec,
+ release_name_success_function success_fn,
+ release_name_fail_function fail_fn,
+ struct userdata_struct *userdata);
+
+/* The following definitions come from nmbd/nmbd_nodestatus.c */
+
+BOOL node_status(struct subnet_record *subrec, struct nmb_name *nmbname,
+ struct in_addr send_ip, node_status_success_function success_fn,
+ node_status_fail_function fail_fn, struct userdata_struct *userdata);
+
+/* The following definitions come from nmbd/nmbd_packets.c */
+
+uint16 get_nb_flags(char *buf);
+void set_nb_flags(char *buf, uint16 nb_flags);
+struct response_record *queue_register_name( struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ register_name_success_function success_fn,
+ register_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ uint16 nb_flags);
+struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ register_name_success_function success_fn,
+ register_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ uint16 nb_flags,
+ struct in_addr register_ip);
+struct response_record *queue_release_name( struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ release_name_success_function success_fn,
+ release_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ uint16 nb_flags,
+ struct in_addr release_ip);
+struct response_record *queue_refresh_name( struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ refresh_name_success_function success_fn,
+ refresh_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct name_record *namerec,
+ struct in_addr refresh_ip);
+struct response_record *queue_query_name( struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ query_name_success_function success_fn,
+ query_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname);
+struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ query_name_success_function success_fn,
+ query_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname);
+struct response_record *queue_node_status( struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ node_status_success_function success_fn,
+ node_status_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ struct in_addr send_ip);
+void reply_netbios_packet(struct packet_struct *orig_packet,
+ int rcode, enum netbios_reply_type_code rcv_code, int opcode,
+ int ttl, char *data,int len);
+void run_packet_queue(void);
+void retransmit_or_expire_response_records(time_t t);
+BOOL listen_for_packets(BOOL run_election);
+BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf,int len,
+ const char *srcname, int src_type,
+ const char *dstname, int dest_type,
+ struct in_addr dest_ip,struct in_addr src_ip,
+ int dest_port);
+
+/* The following definitions come from nmbd/nmbd_processlogon.c */
+
+void process_logon_packet(struct packet_struct *p,char *buf,int len,
+ const char *mailslot);
+
+/* The following definitions come from nmbd/nmbd_responserecordsdb.c */
+
+void remove_response_record(struct subnet_record *subrec,
+ struct response_record *rrec);
+struct response_record *make_response_record( struct subnet_record *subrec,
+ struct packet_struct *p,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ success_function success_fn,
+ fail_function fail_fn,
+ struct userdata_struct *userdata);
+struct response_record *find_response_record(struct subnet_record **ppsubrec,
+ uint16 id);
+BOOL is_refresh_already_queued(struct subnet_record *subrec, struct name_record *namerec);
+
+/* The following definitions come from nmbd/nmbd_sendannounce.c */
+
+void send_browser_reset(int reset_type, const char *to_name, int to_type, struct in_addr to_ip);
+void broadcast_announce_request(struct subnet_record *subrec, struct work_record *work);
+void announce_my_server_names(time_t t);
+void announce_my_lm_server_names(time_t t);
+void reset_announce_timer(void);
+void announce_myself_to_domain_master_browser(time_t t);
+void announce_my_servers_removed(void);
+void announce_remote(time_t t);
+void browse_sync_remote(time_t t);
+
+/* The following definitions come from nmbd/nmbd_serverlistdb.c */
+
+void remove_all_servers(struct work_record *work);
+struct server_record *find_server_in_workgroup(struct work_record *work, char *name);
+void remove_server_from_workgroup(struct work_record *work, struct server_record *servrec);
+struct server_record *create_server_on_workgroup(struct work_record *work,
+ char *name,int servertype,
+ int ttl,char *comment);
+void update_server_ttl(struct server_record *servrec, int ttl);
+void expire_servers(struct work_record *work, time_t t);
+void write_browse_list_entry(FILE *fp, fstring name, uint32 rec_type,
+ fstring local_master_browser_name, fstring description);
+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);
+struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec);
+
+/* The following definitions come from nmbd/nmbd_synclists.c */
+
+void sync_browse_lists(struct work_record *work,
+ char *name, int nm_type,
+ struct in_addr ip, BOOL local, BOOL servers);
+void sync_check_completion(void);
+
+/* The following definitions come from nmbd/nmbd_winsproxy.c */
+
+void make_wins_proxy_name_query_request( struct subnet_record *subrec,
+ struct packet_struct *incoming_packet,
+ struct nmb_name *question_name);
+
+/* The following definitions come from nmbd/nmbd_winsserver.c */
+
+BOOL packet_is_for_wins_server(struct packet_struct *packet);
+BOOL initialise_wins(void);
+void wins_process_name_refresh_request(struct subnet_record *subrec,
+ struct packet_struct *p);
+void wins_process_name_registration_request(struct subnet_record *subrec,
+ struct packet_struct *p);
+void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
+ struct packet_struct *p);
+void send_wins_name_query_response(int rcode, struct packet_struct *p,
+ struct name_record *namerec);
+void wins_process_name_query_request(struct subnet_record *subrec,
+ struct packet_struct *p);
+void wins_process_name_release_request(struct subnet_record *subrec,
+ struct packet_struct *p);
+void initiate_wins_processing(time_t t);
+void wins_write_database(BOOL background);
+
+/* The following definitions come from nmbd/nmbd_workgroupdb.c */
+
+struct work_record *find_workgroup_on_subnet(struct subnet_record *subrec,
+ const char *name);
+struct work_record *create_workgroup_on_subnet(struct subnet_record *subrec,
+ const char *name, int ttl);
+void update_workgroup_ttl(struct work_record *work, int ttl);
+void initiate_myworkgroup_startup(struct subnet_record *subrec, struct work_record *work);
+void dump_workgroups(BOOL force_write);
+void expire_workgroups_and_servers(time_t t);
+
+/* The following definitions come from nsswitch/wb_client.c */
+
+BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
+ enum SID_NAME_USE *name_type);
+BOOL winbind_lookup_sid(DOM_SID *sid,
+ fstring dom_name, fstring name,
+ enum SID_NAME_USE *name_type);
+BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid);
+BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid);
+BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid);
+BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid);
+int winbind_initgroups(char *user, gid_t gid);
+int winbind_getgroups(const char *user, int size, gid_t *list);
+BOOL winbind_uidtoname(fstring name, uid_t uid);
+BOOL winbind_gidtoname(fstring name, gid_t gid);
+BOOL winbind_nametouid(uid_t *puid, const char *name);
+BOOL winbind_nametogid(gid_t *pgid, const char *gname);
+
+/* The following definitions come from nsswitch/wb_common.c */
+
+void free_response(struct winbindd_response *response);
+void winbind_exclude_domain(const char *domain);
+void init_request(struct winbindd_request *request, int request_type);
+void init_response(struct winbindd_response *response);
+void close_sock(void);
+int winbind_open_pipe_sock(void);
+int write_sock(void *buffer, int count);
+int read_reply(struct winbindd_response *response);
+
+/* The following definitions come from param/loadparm.c */
+
+void lp_talloc_free(void);
+char *lp_logfile(void);
+char *lp_configfile(void);
+char *lp_tdb_passwd_file(void);
+char *lp_smb_passwd_file(void);
+char *lp_serverstring(void);
+char *lp_printcapname(void);
+char *lp_enumports_cmd(void);
+char *lp_addprinter_cmd(void);
+char *lp_deleteprinter_cmd(void);
+char *lp_os2_driver_map(void);
+char *lp_lockdir(void);
+char *lp_piddir(void);
+char *lp_utmpdir(void);
+char *lp_wtmpdir(void);
+BOOL lp_utmp(void);
+char *lp_rootdir(void);
+char *lp_source_environment(void);
+char *lp_defaultservice(void);
+char *lp_msg_command(void);
+char *lp_dfree_command(void);
+char *lp_hosts_equiv(void);
+char *lp_auto_services(void);
+char *lp_passwd_program(void);
+char *lp_passwd_chat(void);
+char *lp_passwordserver(void);
+char *lp_name_resolve_order(void);
+char *lp_workgroup(void);
+char *lp_username_map(void);
+char *lp_groupname_map(void);
+char *lp_logon_script(void);
+char *lp_logon_path(void);
+char *lp_logon_drive(void);
+char *lp_logon_home(void);
+char *lp_remote_announce(void);
+char *lp_remote_browse_sync(void);
+char *lp_wins_server(void);
+char *lp_interfaces(void);
+char *lp_socket_address(void);
+char *lp_nis_home_map_name(void);
+char *lp_netbios_aliases(void);
+char *lp_panic_action(void);
+char *lp_adduser_script(void);
+char *lp_deluser_script(void);
+char *lp_wins_hook(void);
+char *lp_domain_admin_group(void);
+char *lp_domain_guest_group(void);
+char *lp_template_homedir(void);
+char *lp_template_shell(void);
+char *lp_winbind_separator(void);
+char *lp_acl_compatibility(void);
+BOOL lp_winbind_enum_users(void);
+BOOL lp_winbind_enum_groups(void);
+BOOL lp_winbind_use_default_domain(void);
+char *lp_codepagedir(void);
+char *lp_ldap_server(void);
+char *lp_ldap_suffix(void);
+char *lp_ldap_filter(void);
+char *lp_ldap_admin_dn(void);
+int lp_ldap_port(void);
+int lp_ldap_ssl(void);
+char *lp_add_share_cmd(void);
+char *lp_change_share_cmd(void);
+char *lp_delete_share_cmd(void);
+char *lp_mangling_method(void);
+int lp_ssl_version(void);
+char *lp_ssl_hosts(void);
+char *lp_ssl_hosts_resign(void);
+char *lp_ssl_cacertdir(void);
+char *lp_ssl_cacertfile(void);
+char *lp_ssl_server_cert(void);
+char *lp_ssl_server_privkey(void);
+char *lp_ssl_client_cert(void);
+char *lp_ssl_client_privkey(void);
+char *lp_ssl_ciphers(void);
+char *lp_ssl_egdsocket(void);
+char *lp_ssl_entropyfile(void);
+int lp_ssl_entropybytes(void);
+BOOL lp_ssl_enabled(void);
+BOOL lp_ssl_reqClientCert(void);
+BOOL lp_ssl_reqServerCert(void);
+BOOL lp_ssl_compatibility(void);
+BOOL lp_ms_add_printer_wizard(void);
+BOOL lp_dns_proxy(void);
+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_logons(void);
+BOOL lp_load_printers(void);
+BOOL lp_use_rhosts(void);
+BOOL lp_readprediction(void);
+BOOL lp_readbmpx(void);
+BOOL lp_readraw(void);
+BOOL lp_large_readwrite(void);
+BOOL lp_writeraw(void);
+BOOL lp_null_passwords(void);
+BOOL lp_obey_pam_restrictions(void);
+BOOL lp_strip_dot(void);
+BOOL lp_encrypted_passwords(void);
+BOOL lp_update_encrypted(void);
+BOOL lp_syslog_only(void);
+BOOL lp_admin_log(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_nis_home_map(void);
+BOOL lp_bind_interfaces_only(void);
+BOOL lp_pam_password_change(void);
+BOOL lp_unix_password_sync(void);
+BOOL lp_passwd_chat_debug(void);
+BOOL lp_nt_smb_support(void);
+BOOL lp_nt_pipe_support(void);
+BOOL lp_nt_status_support(void);
+BOOL lp_stat_cache(void);
+BOOL lp_allow_trusted_domains(void);
+BOOL lp_restrict_anonymous(void);
+BOOL lp_lanman_auth(void);
+BOOL lp_host_msdfs(void);
+BOOL lp_kernel_oplocks(void);
+BOOL lp_enhanced_browsing(void);
+BOOL lp_use_mmap(void);
+BOOL lp_unix_extensions(void);
+int lp_os_level(void);
+int lp_max_ttl(void);
+int lp_max_wins_ttl(void);
+int lp_min_wins_ttl(void);
+int lp_max_log_size(void);
+int lp_max_open_files(void);
+int lp_maxxmit(void);
+int lp_maxmux(void);
+int lp_passwordlevel(void);
+int lp_usernamelevel(void);
+int lp_readsize(void);
+int lp_deadtime(void);
+int lp_maxprotocol(void);
+int lp_minprotocol(void);
+int lp_security(void);
+int lp_maxdisksize(void);
+int lp_lpqcachetime(void);
+int lp_max_smbd_processes(void);
+int lp_disable_spoolss(void);
+int lp_totalprintjobs(void);
+int lp_syslog(void);
+int lp_client_code_page(void);
+int lp_lm_announce(void);
+int lp_lm_interval(void);
+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_lock_spin_count(void);
+int lp_lock_sleep_time(void);
+int lp_name_cache_timeout(void);
+char *lp_preexec(int );
+char *lp_postexec(int );
+char *lp_rootpreexec(int );
+char *lp_rootpostexec(int );
+char *lp_servicename(int );
+char *lp_pathname(int );
+char *lp_dontdescend(int );
+char *lp_username(int );
+char *lp_guestaccount(int );
+char *lp_invalid_users(int );
+char *lp_valid_users(int );
+char *lp_admin_users(int );
+char *lp_printcommand(int );
+char *lp_lpqcommand(int );
+char *lp_lprmcommand(int );
+char *lp_lppausecommand(int );
+char *lp_lpresumecommand(int );
+char *lp_queuepausecommand(int );
+char *lp_queueresumecommand(int );
+char *lp_driverfile(int );
+char *lp_printerdriver(int );
+char *lp_hostsallow(int );
+char *lp_hostsdeny(int );
+char *lp_magicscript(int );
+char *lp_magicoutput(int );
+char *lp_comment(int );
+char *lp_force_user(int );
+char *lp_force_group(int );
+char *lp_readlist(int );
+char *lp_writelist(int );
+char *lp_printer_admin(int );
+char *lp_fstype(int );
+char *lp_vfsobj(int );
+char *lp_vfs_options(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_msdfs_root(int );
+BOOL lp_autoloaded(int );
+BOOL lp_preexec_close(int );
+BOOL lp_rootpreexec_close(int );
+BOOL lp_casesensitive(int );
+BOOL lp_preservecase(int );
+BOOL lp_shortpreservecase(int );
+BOOL lp_casemangle(int );
+BOOL lp_status(int );
+BOOL lp_hide_dot_files(int );
+BOOL lp_hideunreadable(int );
+BOOL lp_browseable(int );
+BOOL lp_readonly(int );
+BOOL lp_no_set_dir(int );
+BOOL lp_guest_ok(int );
+BOOL lp_guest_only(int );
+BOOL lp_print_ok(int );
+BOOL lp_postscript(int );
+BOOL lp_map_hidden(int );
+BOOL lp_map_archive(int );
+BOOL lp_locking(int );
+BOOL lp_strict_locking(int );
+BOOL lp_share_modes(int );
+BOOL lp_posix_locking(int );
+BOOL lp_oplocks(int );
+BOOL lp_level2_oplocks(int );
+BOOL lp_onlyuser(int );
+BOOL lp_manglednames(int );
+BOOL lp_widelinks(int );
+BOOL lp_symlinks(int );
+BOOL lp_syncalways(int );
+BOOL lp_strict_allocate(int );
+BOOL lp_strict_sync(int );
+BOOL lp_map_system(int );
+BOOL lp_delete_readonly(int );
+BOOL lp_fake_oplocks(int );
+BOOL lp_recursive_veto_delete(int );
+BOOL lp_dos_filemode(int );
+BOOL lp_dos_filetimes(int );
+BOOL lp_dos_filetime_resolution(int );
+BOOL lp_fake_dir_create_times(int );
+BOOL lp_blocking_locks(int );
+BOOL lp_inherit_perms(int );
+BOOL lp_inherit_acls(int );
+BOOL lp_use_client_driver(int );
+BOOL lp_default_devmode(int );
+BOOL lp_nt_acl_support(int );
+BOOL lp_force_unknown_acl_user(int );
+BOOL lp_use_sendfile(int );
+BOOL lp_profile_acls(int );
+int lp_create_mask(int );
+int lp_force_create_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_csc_policy(int );
+int lp_write_cache_size(int );
+int lp_block_size(int );
+char lp_magicchar(int );
+int lp_winbind_cache_time(void);
+BOOL lp_hide_local_users(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);
+BOOL lp_file_list_changed(void);
+BOOL lp_winbind_uid(uid_t *low, uid_t *high);
+BOOL lp_winbind_gid(gid_t *low, gid_t *high);
+void *lp_local_ptr(int snum, void *ptr);
+BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue);
+void init_locals(void);
+BOOL lp_is_default(int snum, struct parm_struct *parm);
+struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters);
+BOOL lp_snum_ok(int iService);
+void lp_add_one_printer(char *name, char *comment);
+BOOL lp_loaded(void);
+void lp_killunused(BOOL (*snumused) (int));
+void lp_killservice(int iServiceIn);
+BOOL lp_load(const 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, int maxtoprint, char *(*dos_to_ext)(const char *));
+void lp_dump_one(FILE * f, BOOL show_defaults, int snum, char *(*dos_to_ext)(const char *));
+int lp_servicenumber(const char *pszServiceName);
+char *volume_label(int snum);
+int lp_server_role(void);
+BOOL lp_domain_master(void);
+BOOL lp_preferred_master(void);
+void lp_remove_service(int snum);
+void lp_copy_service(int snum, char *new_name);
+int lp_default_server_announce(void);
+int lp_major_announce_version(void);
+int lp_minor_announce_version(void);
+void lp_set_name_resolve_order(char *new_order);
+char *lp_printername(int snum);
+void get_private_directory(pstring priv_dir);
+void lp_set_logfile(const char *name);
+const char *get_called_name(void);
+int lp_maxprintjobs(int snum);
+
+/* The following definitions come from param/params.c */
+
+BOOL pm_process( char *FileName,
+ BOOL (*sfunc)(char *),
+ BOOL (*pfunc)(char *, char *) );
+
+/* The following definitions come from passdb/machine_sid.c */
+
+BOOL pdb_generate_sam_sid(void);
+
+/* The following definitions come from passdb/pampass.c */
+
+BOOL smb_pam_claim_session(char *user, char *tty, char *rhost);
+BOOL smb_pam_close_session(char *user, char *tty, char *rhost);
+NTSTATUS smb_pam_accountcheck(const char * user);
+NTSTATUS smb_pam_passcheck(char * user, char * password);
+BOOL smb_pam_passchange(const char * user, const char * oldpassword, const char * newpassword);
+NTSTATUS smb_pam_accountcheck(const char * user);
+BOOL smb_pam_claim_session(char *user, char *tty, char *rhost);
+BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost);
+
+/* The following definitions come from passdb/pass_check.c */
+
+void dfs_unlogin(void);
+BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd,
+ BOOL (*fn) (char *, char *));
+
+/* The following definitions come from passdb/passdb.c */
+
+BOOL initialize_password_db(BOOL reload);
+BOOL pdb_init_sam(SAM_ACCOUNT **user);
+BOOL pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, struct passwd *pwd);
+BOOL pdb_reset_sam(SAM_ACCOUNT *user);
+BOOL pdb_free_sam(SAM_ACCOUNT *user);
+struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user);
+char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
+uint16 pdb_decode_acct_ctrl(const char *p);
+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);
+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 local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use);
+BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use);
+DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid);
+BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type);
+DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid);
+BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type);
+void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from);
+void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from);
+void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from);
+BOOL local_password_change(const char *user_name, int local_flags,
+ const char *new_passwd,
+ char *err_str, size_t err_str_len,
+ char *msg_str, size_t msg_str_len);
+uint16 pdb_get_acct_ctrl (SAM_ACCOUNT *sampass);
+time_t pdb_get_logon_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_logoff_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_kickoff_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_pass_last_set_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_pass_can_change_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_pass_must_change_time (SAM_ACCOUNT *sampass);
+uint16 pdb_get_logon_divs (SAM_ACCOUNT *sampass);
+uint32 pdb_get_hours_len (SAM_ACCOUNT *sampass);
+uint8* pdb_get_hours (SAM_ACCOUNT *sampass);
+uint8* pdb_get_nt_passwd (SAM_ACCOUNT *sampass);
+uint8* pdb_get_lanman_passwd (SAM_ACCOUNT *sampass);
+uint32 pdb_get_user_rid (SAM_ACCOUNT *sampass);
+uint32 pdb_get_group_rid (SAM_ACCOUNT *sampass);
+uid_t pdb_get_uid (SAM_ACCOUNT *sampass);
+gid_t pdb_get_gid (SAM_ACCOUNT *sampass);
+char* pdb_get_username (SAM_ACCOUNT *sampass);
+char* pdb_get_domain (SAM_ACCOUNT *sampass);
+char* pdb_get_nt_username (SAM_ACCOUNT *sampass);
+char* pdb_get_fullname (SAM_ACCOUNT *sampass);
+char* pdb_get_homedir (SAM_ACCOUNT *sampass);
+char* pdb_get_dirdrive (SAM_ACCOUNT *sampass);
+char* pdb_get_logon_script (SAM_ACCOUNT *sampass);
+char* pdb_get_profile_path (SAM_ACCOUNT *sampass);
+char* pdb_get_acct_desc (SAM_ACCOUNT *sampass);
+char* pdb_get_workstations (SAM_ACCOUNT *sampass);
+char* pdb_get_munged_dial (SAM_ACCOUNT *sampass);
+uint32 pdb_get_unknown3 (SAM_ACCOUNT *sampass);
+uint32 pdb_get_unknown5 (SAM_ACCOUNT *sampass);
+uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass);
+BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags);
+BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len);
+BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours);
+BOOL pdb_set_init_flag (SAM_ACCOUNT *sampass, uint32 flag);
+BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid);
+BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid);
+BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid);
+BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid);
+BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username);
+BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain);
+BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username);
+BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname);
+BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script, BOOL store);
+BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path, BOOL store);
+BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive, BOOL store);
+BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir, BOOL store);
+BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc);
+BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations);
+BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial);
+BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, uint8 *pwd);
+BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, uint8 *pwd);
+BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext);
+BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn);
+BOOL pdb_set_unknown_5 (SAM_ACCOUNT *sampass, uint32 unkn);
+BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn);
+BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours);
+BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid);
+
+/* The following definitions come from passdb/pdb_ldap.c */
+
+BOOL pdb_setsampwent(BOOL update);
+void pdb_endsampwent(void);
+BOOL pdb_getsampwent(SAM_ACCOUNT * user);
+BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname);
+BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid);
+BOOL pdb_delete_sam_account(const char *sname);
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override);
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd);
+
+/* The following definitions come from passdb/pdb_nisplus.c */
+
+BOOL pdb_setsampwent(BOOL update);
+void pdb_endsampwent(void);
+BOOL pdb_getsampwent(SAM_ACCOUNT *user);
+BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname);
+BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid);
+BOOL pdb_delete_sam_account(const char *sname);
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd);
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override);
+
+/* The following definitions come from passdb/pdb_smbpasswd.c */
+
+BOOL pdb_setsampwent (BOOL update);
+void pdb_endsampwent (void);
+BOOL pdb_getsampwent(SAM_ACCOUNT *user);
+BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username);
+BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct,uint32 rid);
+BOOL pdb_add_sam_account(SAM_ACCOUNT *sampass);
+BOOL pdb_update_sam_account(SAM_ACCOUNT *sampass, BOOL override);
+BOOL pdb_delete_sam_account (const char* username);
+
+/* The following definitions come from passdb/pdb_tdb.c */
+
+BOOL pdb_setsampwent(BOOL update);
+void pdb_endsampwent(void);
+BOOL pdb_getsampwent(SAM_ACCOUNT *user);
+BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname);
+BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid);
+BOOL pdb_delete_sam_account(const char *sname);
+BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override);
+BOOL pdb_add_sam_account (SAM_ACCOUNT *newpwd);
+
+/* The following definitions come from passdb/secrets.c */
+
+BOOL secrets_init(void);
+void *secrets_fetch(const char *key, size_t *size);
+BOOL secrets_store(const char *key, const void *data, size_t size);
+BOOL secrets_delete(const char *key);
+BOOL secrets_store_domain_sid(const char *domain, DOM_SID *sid);
+BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid);
+const char *trust_keystr(const char *domain);
+BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock);
+BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
+ time_t *pass_last_set_time);
+BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16]);
+BOOL trust_password_delete(const char *domain);
+void reset_globals_after_fork(void);
+BOOL secrets_store_ldap_pw(const char* dn, const char* pw);
+BOOL fetch_ldap_pw(const char *dn, char* pw, int len);
+BOOL secrets_named_mutex(const char *name, unsigned int timeout);
+void secrets_named_mutex_release(const char *name);
+
+/* The following definitions come from passdb/smbpassfile.c */
+
+BOOL migrate_from_old_password_file(char *domain);
+
+/* The following definitions come from printing/load.c */
+
+void add_all_printers(void);
+void load_printers(void);
+
+/* The following definitions come from printing/lpq_parse.c */
+
+BOOL parse_lpq_entry(int snum,char *line,
+ print_queue_struct *buf,
+ print_status_struct *status,BOOL first);
+
+/* The following definitions come from printing/nt_printing.c */
+
+BOOL nt_printing_init(void);
+uint32 update_c_setprinter(BOOL initialize);
+uint32 get_c_setprinter(void);
+int get_builtin_ntforms(nt_forms_struct **list);
+BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form);
+int get_ntforms(nt_forms_struct **list);
+int write_ntforms(nt_forms_struct **list, int number);
+BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count);
+BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret);
+void update_a_form(nt_forms_struct **list, const FORM *form, int count);
+int get_ntdrivers(fstring **list, char *architecture, uint32 version);
+BOOL get_short_archi(char *short_archi, const char *long_archi);
+WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+ uint32 level, struct current_user *user);
+BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
+ struct current_user *user, WERROR *perr);
+uint32 get_a_printer_driver_9x_compatible(pstring line, const fstring model);
+uint32 del_a_printer(char *sharename);
+void 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);
+void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr);
+NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename);
+NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode);
+void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr);
+void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname);
+WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
+BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level);
+BOOL del_driver_init(char *drivername);
+uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level);
+WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param);
+WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename);
+uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level);
+uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
+WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
+ fstring drivername, const fstring architecture, uint32 version);
+uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
+BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 );
+WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
+ uint32 version, BOOL delete_files );
+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);
+WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr);
+BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secdesc_ctr);
+void map_printer_permissions(SEC_DESC *sd);
+BOOL print_access_check(struct current_user *user, int snum, int access_type);
+BOOL print_time_access_check(int snum);
+WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default);
+
+/* The following definitions come from printing/pcap.c */
+
+BOOL pcap_printername_ok(char *pszPrintername, const 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(const char *name);
+
+/* The following definitions come from printing/printfsp.c */
+
+files_struct *print_fsp_open(connection_struct *conn, char *fname);
+void print_fsp_end(files_struct *fsp, BOOL normal_close);
+
+/* The following definitions come from printing/print_generic.c */
+
+
+/* The following definitions come from printing/printing.c */
+
+BOOL print_backend_init(void);
+BOOL print_job_exists(int jobid);
+int print_job_snum(int jobid);
+int print_job_fd(int jobid);
+char *print_job_fname(int jobid);
+BOOL print_job_set_place(int jobid, int place);
+BOOL print_job_set_name(int jobid, char *name);
+BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode);
+BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode);
+BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode);
+int print_job_write(int jobid, const char *buf, int size);
+int print_queue_length(int snum, print_status_struct *pstatus);
+int print_job_start(struct current_user *user, int snum, char *jobname);
+void print_job_endpage(int jobid);
+BOOL print_job_end(int jobid, BOOL normal_close);
+int print_queue_status(int snum,
+ print_queue_struct **queue,
+ print_status_struct *status);
+int print_queue_snum(char *qname);
+BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode);
+BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode);
+BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode);
+
+/* The following definitions come from printing/print_svid.c */
+
+void sysv_printer_fn(void (*fn)(char *, char *));
+int sysv_printername_ok(char *name);
+
+/* The following definitions come from profile/profile.c */
+
+void profile_message(int msg_type, pid_t src, void *buf, size_t len);
+void reqprofile_message(int msg_type, pid_t src, void *buf, size_t len);
+BOOL profile_setup(BOOL rdonly);
+
+/* The following definitions come from rpc_client/cli_login.c */
+
+NTSTATUS 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);
+NTSTATUS cli_nt_login_interactive(struct cli_state *cli, char *unix_domain, char *unix_username,
+ uint32 smb_userid_low, char *unix_password,
+ NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+NTSTATUS cli_nt_login_network(struct cli_state *cli, char *unix_domain, char *unix_username,
+ uint32 smb_userid_low, const char lm_chal[8],
+ const char *lm_chal_resp, const char *nt_chal_resp,
+ 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_netlogon.c */
+
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, NTSTATUS status_level);
+NTSTATUS 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]);
+NTSTATUS 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);
+
+/* The following definitions come from rpc_client/cli_pipe.c */
+
+BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
+ prs_struct *data, prs_struct *rdata);
+BOOL rpc_pipe_bind(struct cli_state *cli, const char *pipe_name, char *my_name);
+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);
+void cli_nt_session_close(struct cli_state *cli);
+
+/* The following definitions come from rpc_client/cli_spoolss_notify.c */
+
+BOOL spoolss_disconnect_from_client( struct cli_state *cli);
+BOOL spoolss_connect_to_client( struct cli_state *cli, char *remote_machine);
+WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *printer, uint32 localprinter, uint32 type,
+ POLICY_HND *handle);
+WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle);
+WERROR cli_spoolss_routerreplyprinter (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 condition, uint32 changd_id);
+WERROR cli_spoolss_reply_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle, PRINTER_MESSAGE_INFO *info,
+ NT_PRINTER_INFO_LEVEL *printer);
+
+/* The following definitions come from rpc_client/cli_trust.c */
+
+BOOL change_trust_account_password( char *domain, const char *remote_machine_list);
+
+/* The following definitions come from rpcclient/cmd_dfs.c */
+
+
+/* The following definitions come from rpcclient/cmd_lsarpc.c */
+
+
+/* The following definitions come from rpcclient/cmd_netlogon.c */
+
+
+/* The following definitions come from rpcclient/cmd_reg.c */
+
+
+/* The following definitions come from rpcclient/cmd_samr.c */
+
+
+/* The following definitions come from rpcclient/cmd_spoolss.c */
+
+BOOL get_short_archi(char *short_archi, const char *long_archi);
+void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch);
+
+/* The following definitions come from rpcclient/cmd_srvsvc.c */
+
+
+/* The following definitions come from rpcclient/display_sec.c */
+
+char *get_sec_mask_str(uint32 type);
+void display_sec_access(SEC_ACCESS *info);
+void display_sec_ace(SEC_ACE *ace);
+void display_sec_acl(SEC_ACL *sec_acl);
+void display_sec_desc(SEC_DESC *sec);
+
+/* The following definitions come from rpcclient/rpcclient.c */
+
+void fetch_machine_sid(struct cli_state *cli);
+int main(int argc, char *argv[]);
+
+/* The following definitions come from rpc_parse/parse_dfs.c */
+
+void init_dfs_q_dfs_exist(DFS_Q_DFS_EXIST *q_d);
+BOOL dfs_io_q_dfs_exist(const char *desc, DFS_Q_DFS_EXIST *q_d, prs_struct *ps, int depth);
+BOOL dfs_io_r_dfs_exist(const char *desc, DFS_R_DFS_EXIST *q_d, prs_struct *ps, int depth);
+BOOL init_dfs_q_dfs_remove(DFS_Q_DFS_REMOVE *q_d, const char *entrypath,
+ const char *servername, const char *sharename);
+BOOL dfs_io_q_dfs_remove(const char *desc, DFS_Q_DFS_REMOVE *q_d, prs_struct *ps, int depth);
+BOOL dfs_io_r_dfs_remove(const char *desc, DFS_R_DFS_REMOVE *r_d, prs_struct *ps, int depth);
+BOOL init_dfs_q_dfs_add(DFS_Q_DFS_ADD *q_d, const char *entrypath, const char *servername,
+ const char *sharename, const char *comment, uint32 flags);
+BOOL dfs_io_q_dfs_add(const char *desc, DFS_Q_DFS_ADD *q_d, prs_struct *ps, int depth);
+BOOL dfs_io_r_dfs_add(const char *desc, DFS_R_DFS_ADD *r_d, prs_struct *ps, int depth);
+BOOL init_dfs_q_dfs_get_info(DFS_Q_DFS_GET_INFO *q_d, const char *entrypath,
+ const char *servername, const char *sharename,
+ uint32 info_level);
+BOOL dfs_io_q_dfs_get_info(const char* desc, DFS_Q_DFS_GET_INFO* q_i, prs_struct* ps, int depth);
+BOOL dfs_io_r_dfs_get_info(const char* desc, DFS_R_DFS_GET_INFO* r_i, prs_struct* ps, int depth);
+BOOL init_dfs_q_dfs_enum(DFS_Q_DFS_ENUM *q_d, uint32 level, DFS_INFO_CTR *ctr);
+BOOL dfs_io_q_dfs_enum(const char *desc, DFS_Q_DFS_ENUM *q_d, prs_struct *ps, int depth);
+BOOL dfs_io_dfs_info_ctr(const char *desc, DFS_INFO_CTR* ctr, uint32 num_entries, uint32 level, prs_struct* ps, int depth);
+BOOL dfs_io_r_dfs_enum(const char *desc, DFS_R_DFS_ENUM *q_d, prs_struct *ps, int depth);
+BOOL dfs_io_dfs_storage_info(const char *desc, DFS_INFO_3* info3, prs_struct *ps, int depth);
+
+/* The following definitions come from rpc_parse/parse_lsa.c */
+
+void init_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
+ uint16 sid_name_use, const char *name, uint32 idx);
+void init_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff);
+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(const char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps,
+ int depth);
+BOOL lsa_io_r_open_pol(const char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps,
+ int depth);
+void init_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, const char *server_name,
+ uint32 attributes, uint32 desired_access,
+ LSA_SEC_QOS *qos);
+BOOL lsa_io_q_open_pol2(const char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps,
+ int depth);
+BOOL lsa_io_r_open_pol2(const char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps,
+ int depth);
+void init_q_query_sec_obj(LSA_Q_QUERY_SEC_OBJ *q_q, const POLICY_HND *hnd,
+ uint32 sec_info);
+BOOL lsa_io_q_query_sec_obj(const char *desc, LSA_Q_QUERY_SEC_OBJ *q_q,
+ prs_struct *ps, int depth);
+BOOL lsa_io_r_query_sec_obj(const char *desc, LSA_R_QUERY_SEC_OBJ *r_u,
+ 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(const char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps,
+ int depth);
+BOOL init_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(const char *desc, LSA_Q_ENUM_TRUST_DOM *q_e,
+ prs_struct *ps, int depth);
+void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
+ const char *domain_name, DOM_SID *domain_sid,
+ NTSTATUS status);
+BOOL lsa_io_r_enum_trust_dom(const char *desc, LSA_R_ENUM_TRUST_DOM *r_e,
+ prs_struct *ps, int depth);
+BOOL lsa_io_dom_query_5(const char *desc, DOM_QUERY_5 *d_q, prs_struct *ps, int depth);
+BOOL lsa_io_r_query(const char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps,
+ int depth);
+void init_lsa_sid_enum(TALLOC_CTX *mem_ctx, LSA_SID_ENUM *sen,
+ int num_entries, DOM_SID *sids);
+void init_q_lookup_sids(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_SIDS *q_l,
+ POLICY_HND *hnd, int num_sids, DOM_SID *sids,
+ uint16 level);
+BOOL lsa_io_q_lookup_sids(const char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps,
+ int depth);
+BOOL lsa_io_r_lookup_sids(const char *desc, LSA_R_LOOKUP_SIDS *r_s,
+ prs_struct *ps, int depth);
+void init_q_lookup_names(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_NAMES *q_l,
+ POLICY_HND *hnd, int num_names, const char **names);
+BOOL lsa_io_q_lookup_names(const char *desc, LSA_Q_LOOKUP_NAMES *q_r,
+ prs_struct *ps, int depth);
+BOOL lsa_io_r_lookup_names(const 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(const char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_close(const char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_q_open_secret(const char *desc, LSA_Q_OPEN_SECRET *q_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_open_secret(const char *desc, LSA_R_OPEN_SECRET *r_c, prs_struct *ps, int depth);
+void init_q_enum_privs(LSA_Q_ENUM_PRIVS *q_q, POLICY_HND *hnd, uint32 enum_context, uint32 pref_max_length);
+BOOL lsa_io_q_enum_privs(const char *desc, LSA_Q_ENUM_PRIVS *q_q, prs_struct *ps, int depth);
+void init_lsa_r_enum_privs(LSA_R_ENUM_PRIVS *r_u, uint32 enum_context,
+ uint32 count, LSA_PRIV_ENTRY *entries);
+BOOL lsa_io_r_enum_privs(const char *desc, LSA_R_ENUM_PRIVS *r_q, prs_struct *ps, int depth);
+void init_lsa_priv_get_dispname(LSA_Q_PRIV_GET_DISPNAME *trn, POLICY_HND *hnd, const char *name, uint16 lang_id, uint16 lang_id_sys);
+BOOL lsa_io_q_priv_get_dispname(const char *desc, LSA_Q_PRIV_GET_DISPNAME *q_q, prs_struct *ps, int depth);
+BOOL lsa_io_r_priv_get_dispname(const char *desc, LSA_R_PRIV_GET_DISPNAME *r_q, prs_struct *ps, int depth);
+void init_lsa_q_enum_accounts(LSA_Q_ENUM_ACCOUNTS *trn, POLICY_HND *hnd, uint32 enum_context, uint32 pref_max_length);
+BOOL lsa_io_q_enum_accounts(const char *desc, LSA_Q_ENUM_ACCOUNTS *q_q, prs_struct *ps, int depth);
+void init_lsa_r_enum_accounts(LSA_R_ENUM_ACCOUNTS *r_u, uint32 enum_context);
+BOOL lsa_io_r_enum_accounts(const char *desc, LSA_R_ENUM_ACCOUNTS *r_q, prs_struct *ps, int depth);
+BOOL lsa_io_q_unk_get_connuser(const char *desc, LSA_Q_UNK_GET_CONNUSER *q_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_unk_get_connuser(const char *desc, LSA_R_UNK_GET_CONNUSER *r_c, prs_struct *ps, int depth);
+void init_lsa_q_open_account(LSA_Q_OPENACCOUNT *trn, POLICY_HND *hnd, DOM_SID *sid, uint32 desired_access);
+BOOL lsa_io_q_open_account(const char *desc, LSA_Q_OPENACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_open_account(const char *desc, LSA_R_OPENACCOUNT *r_c, prs_struct *ps, int depth);
+void init_lsa_q_enum_privsaccount(LSA_Q_ENUMPRIVSACCOUNT *trn, POLICY_HND *hnd);
+BOOL lsa_io_q_enum_privsaccount(const char *desc, LSA_Q_ENUMPRIVSACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_luid(const char *desc, LUID *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_luid_attr(const char *desc, LUID_ATTR *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_privilege_set(const char *desc, PRIVILEGE_SET *r_c, prs_struct *ps, int depth);
+void init_lsa_r_enum_privsaccount(LSA_R_ENUMPRIVSACCOUNT *r_u, LUID_ATTR *set, uint32 count, uint32 control);
+BOOL lsa_io_r_enum_privsaccount(const char *desc, LSA_R_ENUMPRIVSACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_q_getsystemaccount(const char *desc, LSA_Q_GETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_getsystemaccount(const char *desc, LSA_R_GETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_q_setsystemaccount(const char *desc, LSA_Q_SETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_setsystemaccount(const char *desc, LSA_R_SETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth);
+void init_lsa_q_lookupprivvalue(LSA_Q_LOOKUPPRIVVALUE *trn, POLICY_HND *hnd, const char *name);
+BOOL lsa_io_q_lookupprivvalue(const char *desc, LSA_Q_LOOKUPPRIVVALUE *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_lookupprivvalue(const char *desc, LSA_R_LOOKUPPRIVVALUE *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_q_addprivs(const char *desc, LSA_Q_ADDPRIVS *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_addprivs(const char *desc, LSA_R_ADDPRIVS *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_q_removeprivs(const char *desc, LSA_Q_REMOVEPRIVS *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_removeprivs(const char *desc, LSA_R_REMOVEPRIVS *r_c, prs_struct *ps, int depth);
+BOOL policy_handle_is_valid(const POLICY_HND *hnd);
+
+/* The following definitions come from rpc_parse/parse_misc.c */
+
+TALLOC_CTX *get_current_rpc_talloc(void);
+void set_current_rpc_talloc( TALLOC_CTX *ctx);
+void main_loop_talloc_free(void);
+TALLOC_CTX *main_loop_talloc_get(void);
+TALLOC_CTX *get_talloc_ctx(void);
+BOOL smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth);
+BOOL smb_io_lookup_level(const char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth);
+uint32 get_enum_hnd(ENUM_HND *enh);
+void init_enum_hnd(ENUM_HND *enh, uint32 hnd);
+BOOL smb_io_enum_hnd(const char *desc, ENUM_HND *hnd, prs_struct *ps, int depth);
+BOOL smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth);
+void init_dom_sid(DOM_SID *sid, const char *str_sid);
+void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid);
+BOOL smb_io_dom_sid2(const 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(const char *desc, STRHDR *hdr, prs_struct *ps, int depth);
+void init_uni_hdr(UNIHDR *hdr, int len);
+BOOL smb_io_unihdr(const 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(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset);
+BOOL smb_io_hdrbuf_post(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
+ uint32 ptr_hdrbuf, uint32 max_len, uint32 len);
+BOOL smb_io_hdrbuf(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth);
+void init_uni_hdr2(UNIHDR2 *hdr, int len);
+BOOL smb_io_unihdr2(const char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth);
+void init_unistr(UNISTR *str, const char *buf);
+BOOL smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth);
+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(const char *desc, BUFFER3 *buf3, prs_struct *ps, int depth);
+BOOL smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
+void init_buffer2(BUFFER2 *str, uint8 *buf, int len);
+BOOL smb_io_buffer2(const char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth);
+void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf);
+void copy_unistr2(UNISTR2 *str, const UNISTR2 *from);
+void init_string2(STRING2 *str, const char *buf, int max_len, int str_len);
+BOOL smb_io_string2(const char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
+void init_unistr2(UNISTR2 *str, const char *buf, size_t len);
+void init_unistr2_from_unistr (UNISTR2 *to, UNISTR *from);
+BOOL smb_io_unistr2(const 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(const 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(const 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, const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name);
+BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth);
+BOOL smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth);
+BOOL smb_io_cred(const char *desc, DOM_CRED *cred, prs_struct *ps, int depth);
+void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED *clnt_cred);
+BOOL smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
+void init_clnt_info(DOM_CLNT_INFO *clnt,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CRED *cred);
+BOOL smb_io_clnt_info(const char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
+void init_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high);
+BOOL smb_io_logon_id(const 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(const char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
+BOOL smb_io_gid(const char *desc, DOM_GID *gid, prs_struct *ps, int depth);
+BOOL smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
+void init_unistr3(UNISTR3 *str, const char *buf);
+BOOL smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth);
+BOOL prs_uint64(const char *name, prs_struct *ps, int depth, UINT64_S *data64);
+BOOL smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth);
+BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_uni_hdr(UNIHDR *hdr, int len);
+BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer);
+
+/* The following definitions come from rpc_parse/parse_net.c */
+
+BOOL net_io_q_logon_ctrl2(const char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth);
+void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, const char *srv_name,
+ uint32 query_level);
+void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
+ uint32 flags, uint32 pdc_status,
+ uint32 logon_attempts, uint32 tc_status,
+ const char *trusted_domain_name);
+BOOL net_io_r_logon_ctrl2(const char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth);
+BOOL net_io_q_logon_ctrl(const char *desc, NET_Q_LOGON_CTRL *q_l, prs_struct *ps,
+ int depth);
+void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, const char *srv_name,
+ uint32 query_level);
+void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level,
+ uint32 flags, uint32 pdc_status);
+BOOL net_io_r_logon_ctrl(const char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps,
+ int depth);
+void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
+ uint32 num_doms, const char *dom_name);
+BOOL net_io_r_trust_dom(const char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth);
+BOOL net_io_q_trust_dom(const 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,
+ const char *logon_srv, const char *logon_clnt,
+ DOM_CHAL *clnt_chal);
+BOOL net_io_q_req_chal(const char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth);
+BOOL net_io_r_req_chal(const char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth);
+BOOL net_io_q_auth(const char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth(const char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth);
+void init_q_auth_2(NET_Q_AUTH_2 *q_a,
+ const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name,
+ DOM_CHAL *clnt_chal, uint32 clnt_flgs);
+BOOL net_io_q_auth_2(const char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth_2(const char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth);
+void init_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(const char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth);
+BOOL net_io_r_srv_pwset(const char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth);
+void init_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
+ uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const char *sess_key,
+ unsigned char lm_cypher[16], unsigned char nt_cypher[16]);
+void init_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,
+ const uchar lm_challenge[8],
+ const uchar * lm_chal_resp, int lm_chal_resp_len,
+ const uchar * nt_chal_resp, int nt_chal_resp_len);
+void init_sam_info(DOM_SAM_INFO *sam,
+ const char *logon_srv, const char *comp_name, DOM_CRED *clnt_cred,
+ DOM_CRED *rtn_cred, uint16 logon_level,
+ NET_ID_INFO_CTR *ctr);
+void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
+ uint16 logon_count, uint16 bad_pw_count,
+ uint32 num_groups, DOM_GID *gids,
+ uint32 user_flgs, uchar *sess_key,
+ const char *logon_srv, const char *logon_dom,
+ DOM_SID *dom_sid, const char *other_sids);
+BOOL net_io_q_sam_logon(const char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
+BOOL net_io_r_sam_logon(const char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
+BOOL net_io_q_sam_logoff(const char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
+BOOL net_io_r_sam_logoff(const char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth);
+BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
+ const char *cli_name, DOM_CRED * cli_creds,
+ DOM_CRED *ret_creds, uint32 database_id);
+BOOL net_io_q_sam_sync(const char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
+ int depth);
+BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ uint32 user_rid, uint32 group_rid,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
+ uint32 acb_info,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str, const UNISTR2 *mung_dial);
+BOOL net_io_r_sam_sync(const char *desc, uint8 sess_key[16],
+ NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth);
+BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name,
+ const char *cli_name, DOM_CRED *cli_creds,
+ uint32 database_id, UINT64_S dom_mod_count);
+BOOL net_io_q_sam_deltas(const char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
+ int depth);
+BOOL net_io_r_sam_deltas(const char *desc, uint8 sess_key[16],
+ NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth);
+
+/* The following definitions come from rpc_parse/parse_prs.c */
+
+void prs_dump(const char *name, int v, prs_struct *ps);
+void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name);
+BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io);
+BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout);
+void prs_mem_free(prs_struct *ps);
+void prs_mem_clear(prs_struct *ps);
+char *prs_alloc_mem(prs_struct *ps, size_t size);
+TALLOC_CTX *prs_get_mem_context(prs_struct *ps);
+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_set_buffer_size(prs_struct *ps, uint32 newsize);
+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_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uint32 len);
+BOOL prs_append_data(prs_struct *dst, char *src, uint32 len);
+void prs_set_endian_data(prs_struct *ps, BOOL endian);
+BOOL prs_align(prs_struct *ps);
+BOOL prs_align_uint16(prs_struct *ps);
+BOOL prs_align_uint64(prs_struct *ps);
+BOOL prs_align_needed(prs_struct *ps, uint32 needed);
+char *prs_mem_get(prs_struct *ps, uint32 extra_size);
+void prs_switch_type(prs_struct *ps, BOOL io);
+void prs_force_dynamic(prs_struct *ps);
+BOOL prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8);
+BOOL prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16);
+BOOL prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32);
+BOOL prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status);
+BOOL prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status);
+BOOL prs_uint8s(BOOL charmode, const char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
+BOOL prs_uint16s(BOOL charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
+BOOL prs_uint16uni(BOOL charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
+BOOL prs_uint32s(BOOL charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
+BOOL prs_buffer5(BOOL charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str);
+BOOL prs_buffer2(BOOL charmode, const char *name, prs_struct *ps, int depth, BUFFER2 *str);
+BOOL prs_string2(BOOL charmode, const char *name, prs_struct *ps, int depth, STRING2 *str);
+BOOL prs_unistr2(BOOL charmode, const char *name, prs_struct *ps, int depth, UNISTR2 *str);
+BOOL prs_unistr3(BOOL charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth);
+BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str);
+BOOL prs_string(const char *name, prs_struct *ps, int depth, char *str, int len, int max_buf_size);
+BOOL prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
+BOOL prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16,
+ uint32 ptr_uint16, uint32 start_offset);
+BOOL prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
+BOOL prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32,
+ uint32 ptr_uint32, uint32 data_size);
+int tdb_prs_store(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps);
+int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *mem_ctx);
+BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16]);
+
+/* The following definitions come from rpc_parse/parse_reg.c */
+
+void init_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
+ uint16 unknown_0, uint32 level);
+BOOL reg_io_q_open_hkcr(const char *desc, REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_open_hkcr(const char *desc, REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth);
+void init_reg_q_open_hklm(REG_Q_OPEN_HKLM * q_o,
+ uint16 unknown_0, uint32 access_mask);
+BOOL reg_io_q_open_hklm(const char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_open_hklm(const char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
+ int depth);
+void init_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol);
+BOOL reg_io_q_flush_key(const char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_flush_key(const char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth);
+void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
+ const char *name, const char *class, SEC_ACCESS *sam_access,
+ SEC_DESC_BUF *sec_buf);
+BOOL reg_io_q_create_key(const char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_create_key(const char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth);
+void init_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
+ const char *name);
+BOOL reg_io_q_delete_val(const char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_delete_val(const char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth);
+void init_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
+ const char *name);
+BOOL reg_io_q_delete_key(const char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_delete_key(const char *desc, REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth);
+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(const char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth);
+void init_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd);
+BOOL reg_io_q_unk_1a(const char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_unk_1a(const char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth);
+void init_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
+ uint16 unknown_0, uint32 level);
+BOOL reg_io_q_open_hku(const char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_open_hku(const char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth);
+void init_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd);
+BOOL reg_io_q_close(const char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth);
+BOOL reg_io_r_close(const char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth);
+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(const char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
+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(const char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_get_key_sec(const char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
+BOOL init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char* val_name);
+BOOL reg_io_q_info(const char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth);
+BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
+ BUFFER2* buf, uint32 type, NTSTATUS status);
+BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth);
+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(const char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth);
+BOOL reg_io_r_enum_val(const char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth);
+void init_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
+ const char *val_name, uint32 type,
+ BUFFER3 *val);
+BOOL reg_io_q_create_val(const char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth);
+BOOL reg_io_r_create_val(const char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth);
+void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx);
+BOOL reg_io_q_enum_key(const char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth);
+BOOL reg_io_r_enum_key(const char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth);
+void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
+ const char *key_name, uint32 unk);
+BOOL reg_io_q_open_entry(const char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth);
+void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
+ POLICY_HND *pol, NTSTATUS status);
+BOOL reg_io_r_open_entry(const char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth);
+void init_reg_q_shutdown(REG_Q_SHUTDOWN * q_s,
+ const char *msg, uint32 timeout, uint16 flags);
+BOOL reg_io_q_shutdown(const char *desc, REG_Q_SHUTDOWN * q_s, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_shutdown(const char *desc, REG_R_SHUTDOWN * r_s, prs_struct *ps,
+ int depth);
+void init_reg_q_abort_shutdown(REG_Q_ABORT_SHUTDOWN * q_s);
+BOOL reg_io_q_abort_shutdown(const char *desc, REG_Q_ABORT_SHUTDOWN * q_s,
+ prs_struct *ps, int depth);
+BOOL reg_io_r_abort_shutdown(const char *desc, REG_R_ABORT_SHUTDOWN * r_s,
+ prs_struct *ps, int depth);
+
+/* The following definitions come from rpc_parse/parse_rpc.c */
+
+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(const char *desc, RPC_HDR *rpc, prs_struct *ps, int depth);
+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(const 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,
+ uint8 num_results, uint16 result, uint16 reason,
+ RPC_IFACE *transfer);
+BOOL smb_io_rpc_hdr_ba(const 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(const char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_resp(const char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_fault(const char *desc, RPC_HDR_FAULT *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(const char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth);
+BOOL rpc_hdr_auth_chk(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(const char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth);
+BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
+ const char *signature, uint32 msg_type);
+void init_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
+ const char *signature, uint32 msg_type);
+BOOL smb_io_rpc_auth_verifier(const 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(const char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth);
+void init_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
+ uint32 neg_flags,
+ uint8 challenge[8]);
+BOOL smb_io_rpc_auth_ntlmssp_chal(const char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth);
+void init_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
+ uchar lm_resp[24], uchar nt_resp[24],
+ const char *domain, const char *user, const char *wks,
+ uint32 neg_flags);
+BOOL smb_io_rpc_auth_ntlmssp_resp(const 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);
+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(const char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth);
+
+/* The following definitions come from rpc_parse/parse_samr.c */
+
+void init_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND *hnd);
+BOOL samr_io_q_close_hnd(const char *desc, SAMR_Q_CLOSE_HND * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_close_hnd(const char *desc, SAMR_R_CLOSE_HND * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN * q_u,
+ POLICY_HND *pol, const char *dom_name);
+BOOL samr_io_q_lookup_domain(const char *desc, SAMR_Q_LOOKUP_DOMAIN * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
+ DOM_SID *dom_sid, NTSTATUS status);
+BOOL samr_io_r_lookup_domain(const char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D * q_u, POLICY_HND *dom_pol, DOM_SID *sid);
+BOOL samr_io_q_unknown_2d(const char *desc, SAMR_Q_UNKNOWN_2D * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_unknown_2d(const char *desc, SAMR_R_UNKNOWN_2D * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN * q_u,
+ POLICY_HND *pol, uint32 flags,
+ const DOM_SID *sid);
+BOOL samr_io_q_open_domain(const char *desc, SAMR_Q_OPEN_DOMAIN * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_open_domain(const char *desc, SAMR_R_OPEN_DOMAIN * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO * q_u,
+ POLICY_HND *user_pol);
+BOOL samr_io_q_get_usrdom_pwinfo(const char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *r_u, NTSTATUS status);
+BOOL samr_io_r_get_usrdom_pwinfo(const char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ * q_u,
+ POLICY_HND *user_pol, uint32 sec_info);
+BOOL samr_io_q_query_sec_obj(const char *desc, SAMR_Q_QUERY_SEC_OBJ * q_u,
+ prs_struct *ps, int depth);
+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(const char *desc, SAMR_Q_QUERY_DOMAIN_INFO * q_u,
+ prs_struct *ps, int depth);
+void init_unk_info3(SAM_UNK_INFO_3 *u_3, NTTIME nt_logout);
+void init_unk_info6(SAM_UNK_INFO_6 * u_6);
+void init_unk_info7(SAM_UNK_INFO_7 * u_7);
+void init_unk_info12(SAM_UNK_INFO_12 * u_12, NTTIME nt_lock_duration, NTTIME nt_reset_time, uint16 lockout);
+void init_unk_info5(SAM_UNK_INFO_5 * u_5,const char *server);
+void init_unk_info2(SAM_UNK_INFO_2 * u_2,
+ const char *domain, const char *server,
+ uint32 seq_num, uint32 num_users, uint32 num_groups, uint32 num_alias);
+void init_unk_info1(SAM_UNK_INFO_1 *u_1, uint16 min_pass_len, uint16 pass_hist,
+ uint32 flag, NTTIME nt_expire, NTTIME nt_min_age);
+void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO * r_u,
+ uint16 switch_value, SAM_UNK_CTR * ctr,
+ NTSTATUS status);
+BOOL samr_io_r_query_dom_info(const char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_query_sec_obj(const char *desc, SAMR_R_QUERY_SEC_OBJ * r_u,
+ prs_struct *ps, int depth);
+void init_sam_entry(SAM_ENTRY * sam, uint32 len_sam_name, uint32 rid);
+void init_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND *pol,
+ uint32 start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size);
+BOOL samr_io_q_enum_dom_users(const char *desc, SAMR_Q_ENUM_DOM_USERS * q_e,
+ prs_struct *ps, int depth);
+void init_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS * r_u,
+ uint32 next_idx, uint32 num_sam_entries);
+BOOL samr_io_r_enum_dom_users(const char *desc, SAMR_R_ENUM_DOM_USERS * 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 max_entries, uint32 max_size);
+BOOL samr_io_q_query_dispinfo(const char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
+ prs_struct *ps, int depth);
+NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_USER_INFO *disp_user_info);
+NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_USER_INFO *disp_user_info);
+NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_GROUP_INFO *disp_group_info);
+NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_USER_INFO *disp_user_info);
+NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_GROUP_INFO *disp_group_info);
+void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO * r_u,
+ uint32 num_entries, uint32 total_size, uint32 data_size,
+ uint16 switch_level, SAM_DISPINFO_CTR * ctr,
+ NTSTATUS status);
+BOOL samr_io_r_query_dispinfo(const char *desc, SAMR_R_QUERY_DISPINFO * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_open_group(SAMR_Q_OPEN_GROUP * q_c,
+ POLICY_HND *hnd,
+ uint32 access_mask, uint32 rid);
+BOOL samr_io_q_open_group(const char *desc, SAMR_Q_OPEN_GROUP * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_open_group(const char *desc, SAMR_R_OPEN_GROUP * r_u,
+ prs_struct *ps, int depth);
+void init_samr_group_info1(GROUP_INFO1 * gr1,
+ const char *acct_name, const char *acct_desc,
+ uint32 num_members);
+BOOL samr_io_group_info1(const char *desc, GROUP_INFO1 * gr1,
+ prs_struct *ps, int depth);
+void init_samr_group_info3(GROUP_INFO3 *gr3);
+BOOL samr_io_group_info3(const char *desc, GROUP_INFO3 *gr3, prs_struct *ps, int depth);
+void init_samr_group_info4(GROUP_INFO4 * gr4, const char *acct_desc);
+BOOL samr_io_group_info4(const char *desc, GROUP_INFO4 * gr4,
+ prs_struct *ps, int depth);
+void init_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP * q_e,
+ POLICY_HND *pol, const char *acct_desc,
+ uint32 access_mask);
+BOOL samr_io_q_create_dom_group(const char *desc, SAMR_Q_CREATE_DOM_GROUP * q_e,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_create_dom_group(const char *desc, SAMR_R_CREATE_DOM_GROUP * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP * q_c,
+ POLICY_HND *hnd);
+BOOL samr_io_q_delete_dom_group(const char *desc, SAMR_Q_DELETE_DOM_GROUP * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_delete_dom_group(const char *desc, SAMR_R_DELETE_DOM_GROUP * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM * q_e,
+ POLICY_HND *pol, uint32 rid);
+BOOL samr_io_q_del_groupmem(const char *desc, SAMR_Q_DEL_GROUPMEM * q_e,
+ prs_struct *ps, int depth);
+void init_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND *pol,
+ NTSTATUS status);
+BOOL samr_io_r_del_groupmem(const char *desc, SAMR_R_DEL_GROUPMEM * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM * q_e,
+ POLICY_HND *pol, uint32 rid);
+BOOL samr_io_q_add_groupmem(const char *desc, SAMR_Q_ADD_GROUPMEM * q_e,
+ prs_struct *ps, int depth);
+void init_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND *pol,
+ NTSTATUS status);
+BOOL samr_io_r_add_groupmem(const char *desc, SAMR_R_ADD_GROUPMEM * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO * q_e,
+ POLICY_HND *pol, GROUP_INFO_CTR * ctr);
+BOOL samr_io_q_set_groupinfo(const char *desc, SAMR_Q_SET_GROUPINFO * q_e,
+ prs_struct *ps, int depth);
+void init_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, NTSTATUS status);
+BOOL samr_io_r_set_groupinfo(const char *desc, SAMR_R_SET_GROUPINFO * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO * q_e,
+ POLICY_HND *pol, uint16 switch_level);
+BOOL samr_io_q_query_groupinfo(const char *desc, SAMR_Q_QUERY_GROUPINFO * q_e,
+ prs_struct *ps, int depth);
+void init_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO * r_u,
+ GROUP_INFO_CTR * ctr, NTSTATUS status);
+BOOL samr_io_r_query_groupinfo(const char *desc, SAMR_R_QUERY_GROUPINFO * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND *hnd);
+BOOL samr_io_q_query_groupmem(const char *desc, SAMR_Q_QUERY_GROUPMEM * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u,
+ uint32 num_entries, uint32 *rid,
+ uint32 *attr, NTSTATUS status);
+BOOL samr_io_r_query_groupmem(const char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS * q_u,
+ POLICY_HND *hnd);
+BOOL samr_io_q_query_usergroups(const 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,
+ NTSTATUS status);
+BOOL samr_io_gids(const char *desc, uint32 *num_gids, DOM_GID ** gid,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_query_usergroups(const char *desc, SAMR_R_QUERY_USERGROUPS * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS * q_e,
+ POLICY_HND *pol,
+ uint32 start_idx, uint32 size);
+BOOL samr_io_q_enum_domains(const char *desc, SAMR_Q_ENUM_DOMAINS * q_e,
+ prs_struct *ps, int depth);
+void init_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS * r_u,
+ uint32 next_idx, uint32 num_sam_entries);
+BOOL samr_io_r_enum_domains(const char *desc, SAMR_R_ENUM_DOMAINS * r_u,
+ prs_struct *ps, int depth);
+void init_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(const 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 next_idx, uint32 num_sam_entries);
+BOOL samr_io_r_enum_dom_groups(const char *desc, SAMR_R_ENUM_DOM_GROUPS * 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 start_idx,
+ uint32 size);
+BOOL samr_io_q_enum_dom_aliases(const 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 next_idx, uint32 num_sam_entries);
+BOOL samr_io_r_enum_dom_aliases(const char *desc, SAMR_R_ENUM_DOM_ALIASES * r_u,
+ prs_struct *ps, int depth);
+void init_samr_alias_info1(ALIAS_INFO1 * al1, const char *acct_name, uint32 num_member, const char *acct_desc);
+BOOL samr_io_alias_info1(const char *desc, ALIAS_INFO1 * al1,
+ prs_struct *ps, int depth);
+void init_samr_alias_info3(ALIAS_INFO3 * al3, const char *acct_desc);
+BOOL samr_io_alias_info3(const char *desc, ALIAS_INFO3 * al3,
+ prs_struct *ps, int depth);
+BOOL samr_alias_info_ctr(const char *desc, ALIAS_INFO_CTR * ctr,
+ 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(const char *desc, SAMR_Q_QUERY_ALIASINFO * q_e,
+ prs_struct *ps, int depth);
+void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO * r_u,
+ ALIAS_INFO_CTR * ctr, NTSTATUS status);
+BOOL samr_io_r_query_aliasinfo(const char *desc, SAMR_R_QUERY_ALIASINFO * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO * q_u,
+ POLICY_HND *hnd, ALIAS_INFO_CTR * ctr);
+BOOL samr_io_q_set_aliasinfo(const char *desc, SAMR_Q_SET_ALIASINFO * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_set_aliasinfo(const char *desc, SAMR_R_SET_ALIASINFO * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES * q_u,
+ POLICY_HND *hnd,
+ uint32 num_sids,
+ uint32 *ptr_sid, DOM_SID2 * sid);
+BOOL samr_io_q_query_useraliases(const char *desc, SAMR_Q_QUERY_USERALIASES * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES * r_u,
+ uint32 num_rids, uint32 *rid,
+ NTSTATUS status);
+BOOL samr_io_rids(const char *desc, uint32 *num_rids, uint32 **rid,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_query_useraliases(const char *desc, SAMR_R_QUERY_USERALIASES * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, POLICY_HND *pol,
+ uint32 access_mask, uint32 rid);
+BOOL samr_io_q_open_alias(const char *desc, SAMR_Q_OPEN_ALIAS * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_open_alias(const char *desc, SAMR_R_OPEN_ALIAS * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_lookup_rids(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_RIDS * q_u,
+ POLICY_HND *pol, uint32 flags,
+ uint32 num_rids, uint32 *rid);
+BOOL samr_io_q_lookup_rids(const char *desc, SAMR_Q_LOOKUP_RIDS * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u,
+ uint32 num_names, UNIHDR * hdr_name,
+ UNISTR2 *uni_name, uint32 *type);
+BOOL samr_io_r_lookup_rids(const char *desc, SAMR_R_LOOKUP_RIDS * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND *hnd);
+BOOL samr_io_q_delete_alias(const char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_delete_alias(const char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
+ prs_struct *ps, int depth);
+void init_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(const char *desc, SAMR_Q_CREATE_DOM_ALIAS * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_create_dom_alias(const char *desc, SAMR_R_CREATE_DOM_ALIAS * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND *hnd,
+ DOM_SID *sid);
+BOOL samr_io_q_add_aliasmem(const char *desc, SAMR_Q_ADD_ALIASMEM * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_add_aliasmem(const char *desc, SAMR_R_ADD_ALIASMEM * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND *hnd,
+ DOM_SID *sid);
+BOOL samr_io_q_del_aliasmem(const char *desc, SAMR_Q_DEL_ALIASMEM * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_del_aliasmem(const char *desc, SAMR_R_DEL_ALIASMEM * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS * q_c,
+ POLICY_HND *hnd);
+BOOL samr_io_q_delete_dom_alias(const char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS * r_u,
+ NTSTATUS status);
+BOOL samr_io_r_delete_dom_alias(const char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM * q_c,
+ POLICY_HND *hnd);
+BOOL samr_io_q_query_aliasmem(const char *desc, SAMR_Q_QUERY_ALIASMEM * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM * r_u,
+ uint32 num_sids, DOM_SID2 * sid,
+ NTSTATUS status);
+BOOL samr_io_r_query_aliasmem(const char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
+ prs_struct *ps, int depth);
+NTSTATUS init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
+ POLICY_HND *pol, uint32 flags,
+ uint32 num_names, const char **name);
+BOOL samr_io_q_lookup_names(const char *desc, SAMR_Q_LOOKUP_NAMES * q_u,
+ prs_struct *ps, int depth);
+NTSTATUS init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
+ uint32 num_rids,
+ uint32 *rid, uint32 *type,
+ NTSTATUS status);
+BOOL samr_io_r_lookup_names(const char *desc, SAMR_R_LOOKUP_NAMES * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER * q_c,
+ POLICY_HND *hnd);
+BOOL samr_io_q_delete_dom_user(const char *desc, SAMR_Q_DELETE_DOM_USER * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_delete_dom_user(const char *desc, SAMR_R_DELETE_DOM_USER * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_open_user(SAMR_Q_OPEN_USER * q_u,
+ POLICY_HND *pol,
+ uint32 access_mask, uint32 rid);
+BOOL samr_io_q_open_user(const char *desc, SAMR_Q_OPEN_USER * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_open_user(const char *desc, SAMR_R_OPEN_USER * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
+ POLICY_HND *pol,
+ const char *name,
+ uint32 acb_info, uint32 access_mask);
+BOOL samr_io_q_create_user(const char *desc, SAMR_Q_CREATE_USER * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_create_user(const char *desc, SAMR_R_CREATE_USER * 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(const char *desc, SAMR_Q_QUERY_USERINFO * q_u,
+ prs_struct *ps, int depth);
+void init_sam_user_info12(SAM_USER_INFO_12 * usr,
+ const uint8 lm_pwd[16], const uint8 nt_pwd[16]);
+void init_sam_user_info10(SAM_USER_INFO_10 * usr, uint32 acb_info);
+void init_sam_user_info11(SAM_USER_INFO_11 * usr,
+ NTTIME * expiry,
+ const char *mach_acct,
+ uint32 rid_user, uint32 rid_group, uint16 acct_ctrl);
+void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516], uint16 pw_len);
+void init_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,
+ 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,
+ uint32 acb_info,
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS * hrs,
+ uint32 unknown_5,
+ char newpass[516], uint32 unknown_6);
+void init_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 */
+ const char *user_name, /* NULL */
+ const char *full_name,
+ const char *home_dir, const char *dir_drive, const char *log_scr,
+ const char *prof_path, const char *desc, const char *wkstas,
+ const char *unk_str, const char *mung_dial, uint32 user_rid, /* 0x0000 0000 */
+ uint32 group_rid, uint32 acb_info,
+ uint32 unknown_3, uint16 logon_divs,
+ LOGON_HRS * hrs, uint32 unknown_5,
+ char newpass[516], uint32 unknown_6);
+void init_sam_user_info21W(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,
+ UNISTR2 *user_name,
+ 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,
+ uchar lm_pwd[16],
+ uchar nt_pwd[16],
+ uint32 user_rid,
+ uint32 group_rid,
+ uint32 acb_info,
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS * hrs,
+ uint32 unknown_5, uint32 unknown_6);
+void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw);
+void init_sam_user_info20A(SAM_USER_INFO_20 *usr, SAM_ACCOUNT *pw);
+NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
+ uint16 switch_value,
+ SAM_USER_INFO_21 * usr);
+void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, uchar * sess_key,
+ uint16 switch_value, void *info);
+void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO * r_u,
+ SAM_USERINFO_CTR * ctr, NTSTATUS status);
+BOOL samr_io_r_query_userinfo(const char *desc, SAMR_R_QUERY_USERINFO * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
+ POLICY_HND *hnd, unsigned char sess_key[16],
+ uint16 switch_value, void *info);
+BOOL samr_io_q_set_userinfo(const char *desc, SAMR_Q_SET_USERINFO * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, NTSTATUS status);
+BOOL samr_io_r_set_userinfo(const char *desc, SAMR_R_SET_USERINFO * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
+ POLICY_HND *hnd, unsigned char sess_key[16],
+ uint16 switch_value, SAM_USERINFO_CTR * ctr);
+BOOL samr_io_q_set_userinfo2(const char *desc, SAMR_Q_SET_USERINFO2 * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, NTSTATUS status);
+BOOL samr_io_r_set_userinfo2(const char *desc, SAMR_R_SET_USERINFO2 * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_connect(SAMR_Q_CONNECT * q_u,
+ const char *srv_name, uint32 access_mask);
+BOOL samr_io_q_connect(const char *desc, SAMR_Q_CONNECT * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_connect(const char *desc, SAMR_R_CONNECT * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_connect_anon(SAMR_Q_CONNECT_ANON * q_u);
+BOOL samr_io_q_connect_anon(const char *desc, SAMR_Q_CONNECT_ANON * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_connect_anon(const char *desc, SAMR_R_CONNECT_ANON * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_get_dom_pwinfo(SAMR_Q_GET_DOM_PWINFO * q_u,
+ const char *srv_name);
+BOOL samr_io_q_get_dom_pwinfo(const char *desc, SAMR_Q_GET_DOM_PWINFO * q_u,
+ prs_struct *ps, int depth);
+BOOL samr_io_r_get_dom_pwinfo(const char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
+ prs_struct *ps, int depth);
+void init_enc_passwd(SAMR_ENC_PASSWD * pwd, char pass[512]);
+BOOL samr_io_enc_passwd(const char *desc, SAMR_ENC_PASSWD * pwd,
+ prs_struct *ps, int depth);
+void init_enc_hash(SAMR_ENC_HASH * hsh, uchar hash[16]);
+BOOL samr_io_enc_hash(const char *desc, SAMR_ENC_HASH * hsh,
+ prs_struct *ps, int depth);
+void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
+ const char *dest_host, const 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(const char *desc, SAMR_Q_CHGPASSWD_USER * q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, NTSTATUS status);
+BOOL samr_io_r_chgpasswd_user(const char *desc, SAMR_R_CHGPASSWD_USER * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_unknown_2e(SAMR_Q_UNKNOWN_2E *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value);
+BOOL samr_io_q_unknown_2e(const char *desc, SAMR_Q_UNKNOWN_2E *q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_samr_unknown_2e(SAMR_R_UNKNOWN_2E * r_u,
+ uint16 switch_value, SAM_UNK_CTR * ctr,
+ NTSTATUS status);
+BOOL samr_io_r_samr_unknown_2e(const char *desc, SAMR_R_UNKNOWN_2E * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_set_domain_info(SAMR_Q_SET_DOMAIN_INFO *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value, SAM_UNK_CTR *ctr);
+BOOL samr_io_q_set_domain_info(const char *desc, SAMR_Q_SET_DOMAIN_INFO *q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_set_domain_info(SAMR_R_SET_DOMAIN_INFO * r_u, NTSTATUS status);
+BOOL samr_io_r_set_domain_info(const char *desc, SAMR_R_SET_DOMAIN_INFO * r_u,
+ prs_struct *ps, int depth);
+
+/* The following definitions come from rpc_parse/parse_sec.c */
+
+void init_sec_access(SEC_ACCESS *t, uint32 mask);
+BOOL sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
+void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
+BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth);
+SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list);
+SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src);
+BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth);
+size_t sec_desc_size(SEC_DESC *psd);
+BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2);
+BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2);
+BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2);
+SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb);
+SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
+ DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size);
+SEC_DESC *dup_sec_desc( TALLOC_CTX *ctx, SEC_DESC *src);
+SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL *dacl, size_t *sd_size);
+BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth);
+SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc);
+SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src);
+BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth);
+
+/* The following definitions come from rpc_parse/parse_spoolss.c */
+
+BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
+BOOL smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
+ prs_struct *ps, int depth);
+BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode);
+BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
+ const fstring printername,
+ const fstring datatype,
+ uint32 access_required,
+ const fstring clientname,
+ const fstring user_name);
+BOOL make_spoolss_q_addprinterex(
+ TALLOC_CTX *mem_ctx,
+ SPOOL_Q_ADDPRINTEREX *q_u,
+ const char *srv_name,
+ const char* clientname,
+ const char* user_name,
+ uint32 level,
+ PRINTER_INFO_CTR *ctr);
+BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
+ PRINTER_INFO_2 *info);
+BOOL spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_open_printer_ex(const char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_deleteprinterdriver(
+ TALLOC_CTX *mem_ctx,
+ SPOOL_Q_DELETEPRINTERDRIVER *q_u,
+ const char *server,
+ const char* arch,
+ const char* driver
+);
+BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
+ const POLICY_HND *handle,
+ UNISTR2 *valuename, uint32 size);
+BOOL spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_deleteprinterdata(const char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_deleteprinterdata(const char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinterdata(const 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_abortprinter(const char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_abortprinter(const char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_deleteprinter(const char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_deleteprinter(const char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_deleteprinterdriver(const char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_deleteprinterdriver(const char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_closeprinter(const char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_closeprinter(const char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_startdocprinter(const char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_startdocprinter(const char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enddocprinter(const char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enddocprinter(const char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_startpageprinter(const char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_startpageprinter(const char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_endpageprinter(const char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_endpageprinter(const char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_writeprinter(const char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_writeprinter(const char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth);
+BOOL smb_io_printer_info_0(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth);
+BOOL smb_io_printer_info_1(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth);
+BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth);
+BOOL smb_io_printer_info_3(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth);
+BOOL smb_io_printer_info_4(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 *info, int depth);
+BOOL smb_io_printer_info_5(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 *info, int depth);
+BOOL smb_io_port_info_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth);
+BOOL smb_io_port_info_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth);
+BOOL smb_io_printer_driver_info_1(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) ;
+BOOL smb_io_printer_driver_info_2(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) ;
+BOOL smb_io_printer_driver_info_3(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth);
+BOOL smb_io_printer_driver_info_6(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth);
+BOOL smb_io_job_info_1(const char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth);
+BOOL smb_io_job_info_2(const char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth);
+BOOL smb_io_form_1(const char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth);
+void spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest);
+uint32 new_get_buffer_size(NEW_BUFFER *buffer);
+BOOL smb_io_driverdir_1(const char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth);
+BOOL smb_io_port_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth);
+BOOL smb_io_port_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth);
+BOOL smb_io_printprocessor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth);
+BOOL smb_io_printprocdatatype_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth);
+BOOL smb_io_printmonitor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth);
+BOOL smb_io_printmonitor_info_2(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth);
+uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info);
+uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info);
+uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info);
+uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info);
+uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info);
+uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info);
+uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info);
+uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info);
+uint32 spoolss_size_string_array(uint16 *string);
+uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info);
+uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info);
+uint32 spoolss_size_job_info_1(JOB_INFO_1 *info);
+uint32 spoolss_size_job_info_2(JOB_INFO_2 *info);
+uint32 spoolss_size_form_1(FORM_1 *info);
+uint32 spoolss_size_port_info_1(PORT_INFO_1 *info);
+uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info);
+uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info);
+uint32 spoolss_size_port_info_2(PORT_INFO_2 *info);
+uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info);
+uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info);
+uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p);
+uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info);
+uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info);
+BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u,
+ const POLICY_HND *hnd,
+ const fstring architecture,
+ uint32 level, uint32 clientmajor, uint32 clientminor,
+ NEW_BUFFER *buffer, uint32 offered);
+BOOL spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_enumprinters(
+ SPOOL_Q_ENUMPRINTERS *q_u,
+ uint32 flags,
+ fstring servername,
+ uint32 level,
+ NEW_BUFFER *buffer,
+ uint32 offered
+);
+BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u,
+ fstring servername, uint32 level,
+ NEW_BUFFER *buffer, uint32 offered);
+BOOL spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_getprinter(
+ TALLOC_CTX *mem_ctx,
+ SPOOL_Q_GETPRINTER *q_u,
+ const POLICY_HND *hnd,
+ uint32 level,
+ NEW_BUFFER *buffer,
+ uint32 offered
+);
+BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u,
+ const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info,
+ uint32 command);
+BOOL spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_fcpn(const char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_fcpn(const char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumjobs(const 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,
+ NEW_BUFFER *buffer,
+ uint32 offered);
+BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_schedulejob(const char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_schedulejob(const char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_setjob(const char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_setjob(const char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
+ const char *name,
+ const char *environment,
+ uint32 level,
+ NEW_BUFFER *buffer, uint32 offered);
+BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth);
+BOOL spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth);
+BOOL spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth);
+BOOL spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth);
+BOOL spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth);
+BOOL spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u,
+ prs_struct *ps, int depth);
+BOOL spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u,
+ prs_struct *ps, int depth);
+BOOL spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u,
+ prs_struct *ps, int depth);
+BOOL smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth);
+BOOL spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth);
+BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
+ SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name,
+ uint32 level, PRINTER_DRIVER_CTR *info);
+BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx,
+ SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
+ DRIVER_INFO_3 *info3);
+BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src);
+BOOL spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_addprinterdriver(const 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_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
+ NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc);
+BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
+ NT_PRINTER_INFO_LEVEL_2 **asc);
+BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
+ fstring servername, fstring env_name, uint32 level,
+ NEW_BUFFER *buffer, uint32 offered);
+BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_addprintprocessor(const char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_addprintprocessor(const char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
+ const POLICY_HND *hnd,
+ uint32 idx, uint32 valuelen, uint32 datalen);
+BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, TALLOC_CTX *ctx, const POLICY_HND *hnd,
+ char* value, char* data);
+BOOL spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_resetprinter(const char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_resetprinter(const char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth);
+BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
+ uint32 type, const uint8 *data, uint32 len);
+BOOL spoolss_io_q_deleteform(const char *desc, SPOOL_Q_DELETEFORM *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_deleteform(const char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_addform(const char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_addform(const char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_setform(const char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_setform(const char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth);
+void free_devmode(DEVICEMODE *devmode);
+void free_printer_info_1(PRINTER_INFO_1 *printer);
+void free_printer_info_2(PRINTER_INFO_2 *printer);
+void free_printer_info_3(PRINTER_INFO_3 *printer);
+void free_printer_info_4(PRINTER_INFO_4 *printer);
+void free_printer_info_5(PRINTER_INFO_5 *printer);
+void free_job_info_2(JOB_INFO_2 *job);
+BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u,
+ const fstring string, uint32 printer, uint32 type);
+BOOL spoolss_io_q_replyopenprinter(const char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_replyopenprinter(const char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_routerreplyprinter(SPOOL_Q_ROUTERREPLYPRINTER *q_u, POLICY_HND *hnd,
+ uint32 condition, uint32 change_id);
+BOOL spoolss_io_q_routerreplyprinter (const char *desc, SPOOL_Q_ROUTERREPLYPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_routerreplyprinter (const char *desc, SPOOL_R_ROUTERREPLYPRINTER *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd);
+BOOL spoolss_io_q_replycloseprinter(const char *desc, SPOOL_Q_REPLYCLOSEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_replycloseprinter(const char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
+ uint32 change_low, uint32 change_high,
+ SPOOL_NOTIFY_INFO *info);
+BOOL spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_getprinterdataex(const char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinterdataex(const char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_setprinterdataex(const char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_setprinterdataex(const char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered);
+BOOL spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth);
+BOOL smb_io_printprocessordirectory_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth);
+BOOL make_spoolss_q_addform(SPOOL_Q_ADDFORM *q_u, POLICY_HND *handle,
+ int level, FORM *form);
+BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle,
+ int level, char *form_name, FORM *form);
+BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle, char *form);
+BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle,
+ char *formname, uint32 level, NEW_BUFFER *buffer,
+ uint32 offered);
+BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle,
+ uint32 level, NEW_BUFFER *buffer,
+ uint32 offered);
+
+/* The following definitions come from rpc_parse/parse_srv.c */
+
+void init_srv_share_info1_str(SH_INFO_1_STR *sh1, const char *net_name, const char *remark);
+void init_srv_share_info1(SH_INFO_1 *sh1, const char *net_name, uint32 type, const char *remark);
+void init_srv_share_info2_str(SH_INFO_2_STR *sh2,
+ const char *net_name, const char *remark,
+ const char *path, const char *passwd);
+void init_srv_share_info2(SH_INFO_2 *sh2,
+ const char *net_name, uint32 type, const char *remark,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ const char *path, const char *passwd);
+void init_srv_share_info501(SH_INFO_501 *sh501, const char *net_name, uint32 type, const char *remark, uint32 csc_policy);
+void init_srv_share_info501_str(SH_INFO_501_STR *sh501, const char *net_name, const char *remark);
+void init_srv_share_info502(SH_INFO_502 *sh502,
+ const char *net_name, uint32 type, const char *remark,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ const char *path, const char *passwd, SEC_DESC *psd, size_t sd_size);
+void init_srv_share_info502_str(SH_INFO_502_STR *sh502str,
+ SH_INFO_502 *ptrs,
+ const char *net_name, const char *remark,
+ const char *path, const char *passwd, SEC_DESC *psd, size_t sd_size);
+void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
+ const char *srv_name, uint32 info_level,
+ uint32 preferred_len, ENUM_HND *hnd);
+BOOL srv_io_q_net_share_enum(const char *desc, SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_share_enum(const char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_share_get_info(const char *desc, SRV_Q_NET_SHARE_GET_INFO *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_share_get_info(const char *desc, SRV_R_NET_SHARE_GET_INFO *r_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_share_set_info(const char *desc, SRV_Q_NET_SHARE_SET_INFO *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_share_set_info(const char *desc, SRV_R_NET_SHARE_SET_INFO *q_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_share_add(const char *desc, SRV_Q_NET_SHARE_ADD *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_share_add(const char *desc, SRV_R_NET_SHARE_ADD *q_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_share_del(const char *desc, SRV_Q_NET_SHARE_DEL *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_share_del(const char *desc, SRV_R_NET_SHARE_DEL *q_n, prs_struct *ps, int depth);
+void init_srv_sess_info0_str(SESS_INFO_0_STR *ss0, const char *name);
+void init_srv_sess_info0(SESS_INFO_0 *ss0, const char *name);
+void init_srv_sess_info1_str(SESS_INFO_1_STR *ss1, const char *name, const char *user);
+void init_srv_sess_info1(SESS_INFO_1 *ss1,
+ const char *name, const char *user,
+ uint32 num_opens, uint32 open_time, uint32 idle_time,
+ uint32 user_flags);
+void init_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
+ const char *srv_name, const char *qual_name,
+ uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_io_q_net_sess_enum(const char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_sess_enum(const 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, const char *usr_name, const 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,
+ const char *usr_name, const char *net_name);
+void init_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,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_io_q_net_conn_enum(const char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_conn_enum(const char *desc, SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps, int depth);
+void init_srv_file_info3_str(FILE_INFO_3_STR *fi3, const char *user_name, const char *path_name);
+void init_srv_file_info3(FILE_INFO_3 *fl3,
+ uint32 id, uint32 perms, uint32 num_locks,
+ const char *path_name, const char *user_name);
+void init_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
+ const char *srv_name, const char *qual_name,
+ uint32 file_level, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_io_q_net_file_enum(const char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_file_enum(const char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth);
+void init_srv_info_100(SRV_INFO_100 *sv100, uint32 platform_id, const char *name);
+void init_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, const char *name,
+ uint32 ver_major, uint32 ver_minor,
+ uint32 srv_type, const char *comment);
+void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, const char *name,
+ const char *comment, uint32 ver_major, uint32 ver_minor,
+ uint32 srv_type, uint32 users, uint32 disc, uint32 hidden,
+ uint32 announce, uint32 ann_delta, uint32 licenses,
+ const char *usr_path);
+void init_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
+ const char *server_name, uint32 switch_value);
+BOOL srv_io_q_net_srv_get_info(const 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, WERROR status);
+void init_srv_r_net_srv_set_info(SRV_R_NET_SRV_SET_INFO *srv,
+ uint32 switch_value, WERROR status);
+BOOL srv_io_q_net_srv_set_info(const char *desc, SRV_Q_NET_SRV_SET_INFO *q_n,
+ prs_struct *ps, int depth);
+BOOL srv_io_r_net_srv_get_info(const char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_srv_set_info(const char *desc, SRV_R_NET_SRV_SET_INFO *r_n,
+ prs_struct *ps, int depth);
+BOOL srv_io_q_net_remote_tod(const 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(const char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_disk_enum(const char *desc, SRV_Q_NET_DISK_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_disk_enum(const char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_name_validate(const char *desc, SRV_Q_NET_NAME_VALIDATE *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_name_validate(const char *desc, SRV_R_NET_NAME_VALIDATE *r_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_file_query_secdesc(const char *desc, SRV_Q_NET_FILE_QUERY_SECDESC *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_file_query_secdesc(const char *desc, SRV_R_NET_FILE_QUERY_SECDESC *r_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_file_set_secdesc(const char *desc, SRV_Q_NET_FILE_SET_SECDESC *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_file_set_secdesc(const char *desc, SRV_R_NET_FILE_SET_SECDESC *r_n, prs_struct *ps, int depth);
+
+/* The following definitions come from rpc_parse/parse_wks.c */
+
+void init_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
+ const char *server, uint16 switch_value) ;
+BOOL wks_io_q_query_info(const char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth);
+void init_wks_info_100(WKS_INFO_100 *inf,
+ uint32 platform_id, uint32 ver_major, uint32 ver_minor,
+ const char *my_name, const char *domain_name);
+void init_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
+ uint32 switch_value, WKS_INFO_100 *wks100,
+ NTSTATUS status) ;
+BOOL wks_io_r_query_info(const char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
+
+/* The following definitions come from rpc_server/srv_dfs.c */
+
+BOOL api_netdfs_rpc(pipes_struct *p);
+
+/* The following definitions come from rpc_server/srv_dfs_nt.c */
+
+uint32 _dfs_exist(pipes_struct *p, DFS_Q_DFS_EXIST *q_u, DFS_R_DFS_EXIST *r_u);
+WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u);
+WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u,
+ DFS_R_DFS_REMOVE *r_u);
+WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u);
+WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u,
+ DFS_R_DFS_GET_INFO *r_u);
+
+/* The following definitions come from rpc_server/srv_lsa.c */
+
+BOOL api_ntlsa_rpc(pipes_struct *p);
+
+/* The following definitions come from rpc_server/srv_lsa_hnd.c */
+
+BOOL init_pipe_handle_list(pipes_struct *p, char *pipe_name);
+BOOL create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void (*free_fn)(void *), void *data_ptr);
+BOOL find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p);
+BOOL close_policy_hnd(pipes_struct *p, POLICY_HND *hnd);
+void close_policy_by_pipe(pipes_struct *p);
+
+/* The following definitions come from rpc_server/srv_lsa_nt.c */
+
+NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u);
+NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u);
+NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u);
+NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u);
+NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u);
+NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u);
+NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u);
+NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u);
+NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u);
+NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u);
+NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u);
+NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u);
+NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u);
+
+/* The following definitions come from rpc_server/srv_netlog.c */
+
+BOOL api_netlog_rpc(pipes_struct *p);
+
+/* The following definitions come from rpc_server/srv_netlog_nt.c */
+
+NTSTATUS _net_logon_ctrl(pipes_struct *p, NET_Q_LOGON_CTRL *q_u,
+ NET_R_LOGON_CTRL *r_u);
+NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u);
+NTSTATUS _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRUST_DOM_LIST *r_u);
+NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u);
+NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u);
+NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u);
+NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u);
+NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u);
+NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u);
+
+/* The following definitions come from rpc_server/srv_pipe.c */
+
+BOOL create_next_pdu(pipes_struct *p);
+BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p);
+BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status);
+BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract,
+ RPC_IFACE* transfer);
+BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p);
+BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in);
+struct current_user *get_current_user(struct current_user *user, pipes_struct *p);
+BOOL api_pipe_request(pipes_struct *p);
+BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name,
+ struct api_struct *api_rpc_cmds);
+
+/* The following definitions come from rpc_server/srv_pipe_hnd.c */
+
+pipes_struct *get_first_pipe(void);
+pipes_struct *get_next_pipe(pipes_struct *p);
+void set_pipe_handle_offset(int max_open_files);
+void reset_chain_p(void);
+void init_rpc_pipe_hnd(void);
+pipes_struct *open_rpc_pipe_p(char *pipe_name,
+ connection_struct *conn, uint16 vuid);
+void free_pipe_context(pipes_struct *p);
+ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n);
+ssize_t read_from_pipe(pipes_struct *p, char *data, size_t 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);
+pipes_struct *get_rpc_pipe_p(char *buf, int where);
+pipes_struct *get_rpc_pipe(int pnum);
+
+/* The following definitions come from rpc_server/srv_reg.c */
+
+BOOL api_reg_rpc(pipes_struct *p);
+
+/* The following definitions come from rpc_server/srv_reg_nt.c */
+
+NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u);
+NTSTATUS _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u);
+NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u);
+NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u);
+
+/* The following definitions come from rpc_server/srv_samr.c */
+
+BOOL api_samr_rpc(pipes_struct *p);
+
+/* The following definitions come from rpc_server/srv_samr_nt.c */
+
+NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u);
+NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u);
+NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u);
+NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u);
+NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u);
+NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u);
+NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u);
+NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u);
+NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u);
+NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u);
+NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u);
+NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u);
+NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u);
+NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u);
+NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u);
+NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u);
+NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u);
+NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u);
+NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u);
+NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u);
+NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u);
+NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u);
+NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u);
+NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u);
+NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u);
+NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u);
+NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u);
+NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u);
+NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u);
+NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u);
+NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u);
+NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u );
+NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u);
+NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u);
+NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u);
+NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u);
+NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u);
+NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u);
+NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u);
+NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u);
+NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u);
+
+/* The following definitions come from rpc_server/srv_spoolss.c */
+
+BOOL api_spoolss_rpc(pipes_struct *p);
+
+/* The following definitions come from rpc_server/srv_spoolss_nt.c */
+
+void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len);
+WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R_OPEN_PRINTER *r_u);
+WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u);
+BOOL convert_devicemode(const char *printername, const DEVICEMODE *devmode,
+ NT_DEVICEMODE **pp_nt_devmode);
+WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u);
+WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u);
+WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
+ SPOOL_R_DELETEPRINTERDRIVER *r_u);
+WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u);
+WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u);
+void spoolss_notify_server_name(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx) ;
+void spoolss_notify_printer_name(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_share_name(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_port_name(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_driver_name(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_comment(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_location(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_sepfile(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_print_processor(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_parameters(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_datatype(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_attributes(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void spoolss_notify_cjobs(int snum,
+ SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer,
+ TALLOC_CTX *mem_ctx);
+void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id);
+WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u);
+WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u);
+WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u);
+WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u);
+WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u);
+WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u);
+WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u);
+WERROR _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u);
+WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u);
+WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u);
+WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u);
+WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u);
+WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u);
+WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u);
+WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u);
+WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u);
+WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u);
+WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u);
+WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u);
+WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u);
+WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u);
+WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u);
+WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u);
+WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u);
+WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u);
+WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u);
+WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u);
+WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u);
+WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u);
+WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u);
+WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u);
+WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u);
+WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u);
+WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u);
+WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u);
+WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u);
+WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u);
+WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u);
+WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u);
+
+/* The following definitions come from rpc_server/srv_srvsvc.c */
+
+BOOL api_srvsvc_rpc(pipes_struct *p);
+
+/* The following definitions come from rpc_server/srv_srvsvc_nt.c */
+
+BOOL share_info_db_init(void);
+void map_generic_share_sd_bits(SEC_DESC *psd);
+BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 desired_access);
+WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u);
+WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u);
+WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u);
+WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u);
+WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u);
+WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u);
+WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u);
+WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u);
+WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u);
+WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u);
+WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u);
+WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u);
+WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
+ SRV_R_NET_FILE_QUERY_SECDESC *r_u);
+WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
+ SRV_R_NET_FILE_SET_SECDESC *r_u);
+WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u);
+WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u);
+
+/* The following definitions come from rpc_server/srv_util.c */
+
+int make_dom_gids(TALLOC_CTX *ctx, char *gids_str, DOM_GID **ppgids);
+void get_domain_user_groups(char *domain_groups, char *user);
+NTSTATUS local_lookup_group_name(uint32 rid, char *group_name, uint32 *type);
+NTSTATUS local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type);
+NTSTATUS local_lookup_user_name(uint32 rid, char *user_name, uint32 *type);
+NTSTATUS local_lookup_group_rid(char *group_name, uint32 *rid);
+NTSTATUS local_lookup_alias_rid(char *alias_name, uint32 *rid);
+NTSTATUS local_lookup_user_rid(char *user_name, uint32 *rid);
+
+/* The following definitions come from rpc_server/srv_wkssvc.c */
+
+BOOL api_wkssvc_rpc(pipes_struct *p);
+
+/* The following definitions come from rpc_server/srv_wkssvc_nt.c */
+
+NTSTATUS _wks_query_info(pipes_struct *p, WKS_Q_QUERY_INFO *q_u, WKS_R_QUERY_INFO *r_u);
+
+/* The following definitions come from smbd/blocking.c */
+
+BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout,
+ int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count);
+void remove_pending_lock_requests_by_fid(files_struct *fsp);
+void remove_pending_lock_requests_by_mid(int mid);
+unsigned blocking_locks_timeout(unsigned default_timeout);
+void process_blocking_lock_queue(time_t t);
+
+/* The following definitions come from smbd/chgpasswd.c */
+
+BOOL chgpasswd(char *name, const char *oldpass, const char *newpass, BOOL as_root);
+BOOL chgpasswd(char *name, const char *oldpass, const char *newpass, BOOL as_root);
+BOOL check_lanman_password(char *user, uchar * pass1,
+ uchar * pass2, SAM_ACCOUNT **hnd);
+BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar * pass1,
+ uchar * pass2);
+BOOL pass_oem_change(char *user,
+ uchar * lmdata, uchar * lmhash,
+ uchar * ntdata, uchar * nthash);
+BOOL check_oem_password(char *user,
+ uchar * lmdata, uchar * lmhash,
+ uchar * ntdata, uchar * nthash,
+ SAM_ACCOUNT **hnd, char *new_passwd,
+ int new_passwd_size);
+BOOL change_oem_password(SAM_ACCOUNT *hnd, char *new_passwd,
+ BOOL override);
+BOOL check_plaintext_password(char *user, char *old_passwd,
+ int old_passwd_size, SAM_ACCOUNT **hnd);
+
+/* The following definitions come from smbd/close.c */
+
+int close_file(files_struct *fsp, BOOL normal_close);
+
+/* The following definitions come from smbd/conn.c */
+
+void conn_init(void);
+int conn_num_open(void);
+BOOL conn_snum_used(int snum);
+connection_struct *conn_find(int cnum);
+connection_struct *conn_new(void);
+void conn_close_all(void);
+BOOL conn_idle_all(time_t t, int deadtime);
+void conn_free(connection_struct *conn);
+void msg_force_tdis(int msg_type, pid_t pid, void *buf, size_t len);
+
+/* The following definitions come from smbd/connection.c */
+
+TDB_CONTEXT *conn_tdb_ctx(void);
+BOOL yield_connection(connection_struct *conn,const char *name);
+BOOL claim_connection(connection_struct *conn,const char *name,int max_connections,BOOL Clear);
+
+/* The following definitions come from smbd/dfree.c */
+
+SMB_BIG_UINT sys_disk_free(const 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 */
+
+void init_dptrs(void);
+char *dptr_path(int key);
+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_closecnum(connection_struct *conn);
+void dptr_idlecnum(connection_struct *conn);
+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);
+void *dptr_fetch(char *buf,int *num);
+void *dptr_fetch_lanman2(int dptr_num);
+BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype);
+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);
+void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto);
+void CloseDir(void *p);
+char *ReadDirName(void *p);
+BOOL SeekDir(void *p,int pos);
+int TellDir(void *p);
+void DirCacheAdd( const char *path, const char *name, const char *dname, int snum );
+char *DirCacheCheck( const char *path, const char *name, int snum );
+void DirCacheFlush(int snum);
+
+/* The following definitions come from smbd/dosmode.c */
+
+mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname);
+int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf);
+int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st);
+int file_utime(connection_struct *conn, char *fname, struct utimbuf *times);
+BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime);
+
+/* The following definitions come from smbd/error.c */
+
+int cached_error_packet(char *outbuf,files_struct *fsp,int line,const char *file);
+int unix_error_packet(char *outbuf,int def_class,uint32 def_code,
+ int line, const char *file);
+int error_packet(char *outbuf,NTSTATUS ntstatus,
+ uint8 eclass,uint32 ecode,int line, const char *file);
+
+/* 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, 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);
+int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst);
+
+/* The following definitions come from smbd/filename.c */
+
+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 */
+
+files_struct *file_new(connection_struct *conn);
+void file_close_conn(connection_struct *conn);
+void file_init(void);
+void file_close_user(int vuid);
+files_struct *file_find_fd(int fd);
+files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id);
+files_struct *file_find_fsp(files_struct *orig_fsp);
+files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode);
+files_struct *file_find_di_next(files_struct *start_fsp);
+files_struct *file_find_print(void);
+void file_sync_all(connection_struct *conn);
+void file_free(files_struct *fsp);
+files_struct *file_fsp(char *buf, int where);
+void file_chain_reset(void);
+void file_chain_save(void);
+void file_chain_restore(void);
+
+/* The following definitions come from smbd/ipc.c */
+
+void send_trans_reply(char *outbuf,
+ char *rparam, int rparam_len,
+ char *rdata, int rdata_len,
+ BOOL buffer_too_large);
+int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize);
+
+/* The following definitions come from smbd/lanman.c */
+
+int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
+ int tdscnt,int tpscnt,int mdrcnt,int mprcnt);
+
+/* The following definitions come from smbd/mangle.c */
+
+void mangle_reset_cache(void);
+BOOL mangle_is_mangled(const char *s);
+BOOL mangle_is_8_3(const char *fname, BOOL check_case);
+BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case);
+BOOL mangle_check_cache(char *s, size_t maxlen);
+void mangle_map(char *OutName, BOOL need83, BOOL cache83, int snum);
+
+/* The following definitions come from smbd/mangle_hash2.c */
+
+struct mangle_fns *mangle_hash2_init(void);
+
+/* The following definitions come from smbd/mangle_hash.c */
+
+struct mangle_fns *mangle_hash_init(void);
+
+/* The following definitions come from smbd/mangle_map.c */
+
+void mangle_map_filename(char *fname, int snum);
+
+/* The following definitions come from smbd/message.c */
+
+int reply_sends(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_sendstrt(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_sendtxt(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_sendend(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+
+/* The following definitions come from smbd/negprot.c */
+
+int reply_negprot(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size,
+ int dum_buffsize);
+
+/* The following definitions come from smbd/noquotas.c */
+
+BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize);
+
+/* The following definitions come from smbd/notify.c */
+
+void remove_pending_change_notify_requests_by_fid(files_struct *fsp);
+void remove_pending_change_notify_requests_by_mid(int mid);
+void remove_pending_change_notify_requests_by_filename(files_struct *fsp);
+int change_notify_timeout(void);
+BOOL process_pending_change_notify_queue(time_t t);
+BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn, uint32 flags);
+BOOL init_change_notify(void);
+
+/* The following definitions come from smbd/notify_hash.c */
+
+struct cnotify_fns *hash_notify_init(void) ;
+
+/* The following definitions come from smbd/notify_kernel.c */
+
+struct cnotify_fns *kernel_notify_init(void) ;
+
+/* The following definitions come from smbd/nttrans.c */
+
+int reply_ntcreate_and_X(connection_struct *conn,
+ char *inbuf,char *outbuf,int length,int bufsize);
+int reply_ntcancel(connection_struct *conn,
+ char *inbuf,char *outbuf,int length,int bufsize);
+int reply_nttranss(connection_struct *conn,
+ char *inbuf,char *outbuf,int length,int bufsize);
+int reply_nttrans(connection_struct *conn,
+ char *inbuf,char *outbuf,int length,int bufsize);
+
+/* The following definitions come from smbd/open.c */
+
+int fd_close(struct connection_struct *conn, files_struct *fsp);
+files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
+ int share_mode,int ofun, mode_t mode,int oplock_request, int *Access,int *action);
+files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
+ uint32 desired_access,
+ int share_mode,int ofun, mode_t mode,int oplock_request,
+ int *Access,int *action);
+files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf);
+int close_file_fchmod(files_struct *fsp);
+files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
+ uint32 desired_access, int share_mode, int smb_ofun, mode_t unixmode, int *action);
+files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf);
+
+/* The following definitions come from smbd/oplock.c */
+
+int32 get_number_of_exclusive_open_oplocks(void);
+BOOL oplock_message_waiting(fd_set *fds);
+BOOL receive_local_message( char *buffer, int buffer_len, int timeout);
+BOOL set_file_oplock(files_struct *fsp, int oplock_type);
+void release_file_oplock(files_struct *fsp);
+BOOL remove_oplock(files_struct *fsp, BOOL break_to_none);
+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, BOOL async);
+BOOL attempt_close_oplocked_file(files_struct *fsp);
+void release_level_2_oplocks_on_change(files_struct *fsp);
+BOOL init_oplocks(void);
+
+/* The following definitions come from smbd/oplock_irix.c */
+
+struct kernel_oplocks *irix_init_kernel_oplocks(void) ;
+
+/* The following definitions come from smbd/oplock_linux.c */
+
+struct kernel_oplocks *linux_init_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);
+void invalidate_all_vuids(void);
+char *validated_username(uint16 vuid);
+char *validated_domain(uint16 vuid);
+NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest, NT_USER_TOKEN *sup_tok);
+int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
+ char *domain,BOOL guest, NT_USER_TOKEN **pptok);
+void add_session_user(char *user);
+BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
+BOOL smb_password_ok(SAM_ACCOUNT *sampass, 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);
+struct cli_state *server_client(void);
+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, NT_USER_TOKEN **pptoken);
+
+/* 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 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/posix_acls.c */
+
+SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T acl);
+size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc);
+BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd);
+int chmod_acl(connection_struct *conn, const char *name, mode_t mode);
+int inherit_access_acl(connection_struct *conn, const char *name, mode_t mode);
+int fchmod_acl(files_struct *fsp, int fd, mode_t mode);
+BOOL directory_has_default_acl(connection_struct *conn, const char *fname);
+
+/* 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);
+const 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 */
+
+int reply_special(char *inbuf,char *outbuf);
+int reply_tcon(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_unknown(char *inbuf,char *outbuf);
+int reply_ioctl(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int smb_create_user(char *unix_user, char *homedir);
+int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name);
+int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+void fail_readraw(void);
+void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
+ ssize_t mincount, char *outbuf);
+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 size, int dum_buffsize);
+int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length,
+ files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt);
+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 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 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 size,
+ int dum_buffsize);
+int reply_writeclose(connection_struct *conn,
+ 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 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,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_printopen(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_printclose(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+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);
+NTSTATUS mkdir_internal(connection_struct *conn, pstring directory);
+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);
+NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists);
+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);
+uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format);
+SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format);
+SMB_BIG_UINT 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_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int 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_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+
+/* The following definitions come from smbd/sec_ctx.c */
+
+int get_current_groups(gid_t gid, int *p_ngroups, gid_t **p_groups);
+void delete_nt_token(NT_USER_TOKEN **pptoken);
+NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken);
+BOOL initialise_groups(char *user, uid_t uid, gid_t gid);
+BOOL push_sec_ctx(void);
+void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token);
+void set_root_sec_ctx(void);
+BOOL pop_sec_ctx(void);
+void init_sec_ctx(void);
+
+/* The following definitions come from smbd/server.c */
+
+int smbd_server_fd(void);
+void smbd_set_server_fd(int fd);
+BOOL allowable_number_of_smbd_processes(void);
+BOOL reload_services(BOOL test);
+int32 increment_smbd_process_count(void);
+void exit_server(const char *reason);
+
+/* The following definitions come from smbd/service.c */
+
+BOOL set_current_service(connection_struct *conn,BOOL do_chdir);
+int add_home_service(char *service, char *homedir);
+int find_service(char *service);
+connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode);
+void close_cnum(connection_struct *conn, uint16 vuid);
+
+/* The following definitions come from smbd/session.c */
+
+BOOL session_claim(uint16 vuid);
+void session_yield(uint16 vuid);
+
+/* The following definitions come from smbd/ssl.c */
+
+int sslutil_init(int isServer);
+int sslutil_accept(int fd);
+int sslutil_fd_is_ssl(int fd);
+int sslutil_connect(int fd);
+int sslutil_disconnect(int fd);
+int sslutil_negotiate_ssl(int fd, int msg_type);
+
+/* The following definitions come from smbd/statcache.c */
+
+void stat_cache_add( char *full_orig_name, char *orig_translated_path);
+BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath,
+ char **start, SMB_STRUCT_STAT *pst);
+BOOL reset_stat_cache( void );
+
+/* The following definitions come from smbd/trans2.c */
+
+SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf);
+time_t interpret_long_unix_date(char *p);
+NTSTATUS set_bad_path_error(int err, BOOL bad_path);
+NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close);
+NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close);
+int reply_findclose(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_findnclose(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_transs2(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+
+/* The following definitions come from smbd/uid.c */
+
+BOOL change_to_guest(void);
+BOOL change_to_user(connection_struct *conn, uint16 vuid);
+BOOL change_to_root_user(void);
+BOOL become_authenticated_pipe_user(pipes_struct *p);
+BOOL unbecome_authenticated_pipe_user(void);
+void init_conn_ctx(void);
+void become_root(void);
+void unbecome_root(void);
+BOOL become_user(connection_struct *conn, uint16 vuid);
+BOOL unbecome_user(void);
+void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER_TOKEN **pptok);
+BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type);
+BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type);
+DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid);
+DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid);
+BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype);
+BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype);
+
+/* The following definitions come from smbd/utmp.c */
+
+void sys_utmp_yield(const char *username, const char *hostname,
+ const char *id_str, int id_num);
+void sys_utmp_claim(const char *username, const char *hostname,
+ const char *id_str, int id_num);
+
+/* The following definitions come from smbd/vfs.c */
+
+BOOL smbd_vfs_init(connection_struct *conn);
+BOOL vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_STAT *st);
+int vfs_mkdir(connection_struct *conn, char *const fname, mode_t mode);
+char *vfs_getwd(connection_struct *conn, char *unix_path);
+BOOL vfs_object_exist(connection_struct *conn, const char *fname,SMB_STRUCT_STAT *sbuf);
+BOOL vfs_file_exist(connection_struct *conn, const char *fname,SMB_STRUCT_STAT *sbuf);
+ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count);
+ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N);
+int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len);
+int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len);
+SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n);
+char *vfs_readdirname(connection_struct *conn, void *p);
+int vfs_ChDir(connection_struct *conn, const char *path);
+char *vfs_GetWd(connection_struct *conn, char *path);
+BOOL reduce_name(connection_struct *conn, char *s,char *dir,BOOL widelinks);
+
+/* The following definitions come from smbd/vfs-wrap.c */
+
+int vfswrap_dummy_connect(connection_struct *conn, const char *service, const char *user);
+void vfswrap_dummy_disconnect(connection_struct *conn);
+SMB_BIG_UINT vfswrap_disk_free(connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+ SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
+DIR *vfswrap_opendir(connection_struct *conn, const char *fname);
+struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp);
+int vfswrap_mkdir(connection_struct *conn, const char *path, mode_t mode);
+int vfswrap_rmdir(connection_struct *conn, const char *path);
+int vfswrap_closedir(connection_struct *conn, DIR *dirp);
+int vfswrap_open(connection_struct *conn, const char *fname, int flags, mode_t mode);
+int vfswrap_close(files_struct *fsp, int fd);
+ssize_t vfswrap_read(files_struct *fsp, int fd, void *data, size_t n);
+ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n);
+ssize_t vfswrap_sendfile(int tofd, struct files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
+ SMB_OFF_T offset, size_t n);
+SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
+int vfswrap_rename(connection_struct *conn, const char *oldname, const char *newname);
+int vfswrap_fsync(files_struct *fsp, int fd);
+int vfswrap_stat(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf);
+int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
+int vfswrap_lstat(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf);
+int vfswrap_unlink(connection_struct *conn, const char *path);
+int vfswrap_chmod(connection_struct *conn, const char *path, mode_t mode);
+int vfswrap_fchmod(files_struct *fsp, int fd, mode_t mode);
+int vfswrap_chown(connection_struct *conn, const char *path, uid_t uid, gid_t gid);
+int vfswrap_fchown(files_struct *fsp, int fd, uid_t uid, gid_t gid);
+int vfswrap_chdir(connection_struct *conn, const char *path);
+char *vfswrap_getwd(connection_struct *conn, char *path);
+int vfswrap_utime(connection_struct *conn, const char *path, struct utimbuf *times);
+int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len);
+BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *newpath);
+int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_t bufsiz);
+int vfswrap_link(connection_struct *conn, const char *oldpath, const char *newpath);
+int vfswrap_mknod(connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev);
+char *vfswrap_realpath(connection_struct *conn, const char *path, char *resolved_path);
+size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc);
+size_t vfswrap_get_nt_acl(files_struct *fsp, const char *name, SEC_DESC **ppdesc);
+BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd);
+BOOL vfswrap_set_nt_acl(files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd);
+int vfswrap_chmod_acl(connection_struct *conn, const char *name, mode_t mode);
+int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode);
+int vfswrap_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int vfswrap_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
+int vfswrap_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void * vfswrap_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T vfswrap_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T vfswrap_sys_acl_get_fd(struct files_struct *fsp, int fd);
+int vfswrap_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset);
+int vfswrap_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+char * vfswrap_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen);
+SMB_ACL_T vfswrap_sys_acl_init(struct connection_struct *conn, int count);
+int vfswrap_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
+int vfswrap_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
+int vfswrap_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual);
+int vfswrap_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
+int vfswrap_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl );
+int vfswrap_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+int vfswrap_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl);
+int vfswrap_sys_acl_delete_def_file(struct connection_struct *conn, const char *path);
+int vfswrap_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+int vfswrap_sys_acl_free_text(struct connection_struct *conn, char *text);
+int vfswrap_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl);
+int vfswrap_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype);
+
+/* The following definitions come from smbwrapper/realcalls.c */
+
+int real_utime(const char *name, struct utimbuf *buf);
+int real_utimes(const char *name, struct timeval tv[2]);
+
+/* The following definitions come from smbwrapper/shared.c */
+
+void smbw_setup_shared(void);
+char *smbw_getshared(const char *name);
+void smbw_setshared(const char *name, const char *val);
+int smbw_setenv(const char *name, const char *value);
+int smbw_shared_fd(int fd);
+
+/* The following definitions come from smbwrapper/smbw.c */
+
+void smbw_init(void);
+int smbw_fd(int fd);
+int smbw_local_fd(int fd);
+ino_t smbw_inode(const char *name);
+void clean_fname(char *name);
+char *smbw_parse_path(const char *fname, char *server, char *share, char *path);
+int smbw_path(const char *path);
+int smbw_errno(struct cli_state *c);
+void get_envvar_auth_data(char *server, char *share, char **workgroup,
+ char **username, char **password);
+void smbw_set_auth_data_fn(smbw_get_auth_data_fn fn);
+struct smbw_server *smbw_server(char *server, char *share);
+struct smbw_file *smbw_file(int fd);
+int smbw_open(const char *fname, int flags, mode_t mode);
+ssize_t smbw_pread(int fd, void *buf, size_t count, off_t ofs);
+ssize_t smbw_read(int fd, void *buf, size_t count);
+ssize_t smbw_write(int fd, void *buf, size_t count);
+ssize_t smbw_pwrite(int fd, void *buf, size_t count, off_t ofs);
+int smbw_close(int fd);
+int smbw_fcntl(int fd, int cmd, long arg);
+int smbw_access(const char *name, int mode);
+int smbw_readlink(const char *path, char *buf, size_t bufsize);
+int smbw_unlink(const char *fname);
+int smbw_rename(const char *oldname, const char *newname);
+int smbw_utime(const char *fname, void *buf);
+int smbw_utimes(const char *fname, void *buf);
+int smbw_chown(const char *fname, uid_t owner, gid_t group);
+int smbw_chmod(const char *fname, mode_t newmode);
+off_t smbw_lseek(int fd, off_t offset, int whence);
+int smbw_dup(int fd);
+int smbw_dup2(int fd, int fd2);
+int smbw_fork(void);
+
+/* The following definitions come from smbwrapper/smbw_dir.c */
+
+struct smbw_dir *smbw_dir(int fd);
+int smbw_dirp(DIR *dirp);
+int smbw_dir_open(const char *fname);
+int smbw_dir_fstat(int fd, struct stat *st);
+int smbw_dir_close(int fd);
+int smbw_getdents(unsigned int fd, struct dirent *dirp, int count);
+int smbw_chdir(const char *name);
+off_t smbw_dir_lseek(int fd, off_t offset, int whence);
+int smbw_mkdir(const char *fname, mode_t mode);
+int smbw_rmdir(const char *fname);
+char *smbw_getcwd(char *buf, size_t size);
+int smbw_fchdir(unsigned int fd);
+DIR *smbw_opendir(const char *fname);
+struct dirent *smbw_readdir(DIR *dirp);
+int smbw_closedir(DIR *dirp);
+void smbw_seekdir(DIR *dirp, off_t offset);
+off_t smbw_telldir(DIR *dirp);
+
+/* The following definitions come from smbwrapper/smbw_stat.c */
+
+void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode);
+BOOL smbw_getatr(struct smbw_server *srv, char *path,
+ uint16 *mode, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ SMB_INO_T *ino);
+int smbw_stat_printjob(struct smbw_server *srv,char *path,
+ size_t *size, time_t *m_time);
+int smbw_fstat(int fd, struct stat *st);
+int smbw_stat(const char *fname, struct stat *st);
+
+/* The following definitions come from tdb/spinlock.c */
+
+int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type);
+int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
+int tdb_create_rwlocks(int fd, unsigned int hash_size);
+int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
+int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
+
+/* The following definitions come from tdb/tdb.c */
+
+void tdb_set_lock_alarm(sig_atomic_t *palarm);
+void tdb_dump_all(TDB_CONTEXT *tdb);
+int tdb_printfreelist(TDB_CONTEXT *tdb);
+enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb);
+const char *tdb_errorstr(TDB_CONTEXT *tdb);
+TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state);
+TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb);
+TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey);
+int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
+int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf);
+TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode);
+TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode,
+ tdb_log_func log_fn);
+int tdb_close(TDB_CONTEXT *tdb);
+int tdb_lockall(TDB_CONTEXT *tdb);
+void tdb_unlockall(TDB_CONTEXT *tdb);
+int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]);
+void tdb_unlockkeys(TDB_CONTEXT *tdb);
+int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key);
+void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...));
+int tdb_reopen(TDB_CONTEXT *tdb);
+int tdb_reopen_all(void);
+
+/* The following definitions come from tdb/tdbutil.c */
+
+int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout);
+int tdb_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout);
+void tdb_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval);
+int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len);
+int32 tdb_fetch_int32(TDB_CONTEXT *tdb, const char *keystr);
+int tdb_store_int32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, int32 v);
+int tdb_store_int32(TDB_CONTEXT *tdb, const char *keystr, int32 v);
+BOOL tdb_fetch_uint32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len, uint32 *value);
+BOOL tdb_fetch_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 *value);
+BOOL tdb_store_uint32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, uint32 value);
+BOOL tdb_store_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 value);
+int tdb_store_by_string(TDB_CONTEXT *tdb, const char *keystr, void *buffer, int len);
+TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, const char *keystr);
+int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, const char *keystr, int32 *oldval, int32 change_val);
+BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, char *keystr, uint32 *oldval, uint32 change_val);
+size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...);
+int tdb_unpack(char *buf, int bufsize, const char *fmt, ...);
+TDB_CONTEXT *tdb_open_log(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode);
+int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
+ void *state);
+
+/* The following definitions come from utils/nbio.c */
+
+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/torture.c */
+
+int cli_setfileinfo_test(struct cli_state *cli, int fnum, int level, char *data, int data_len);
+
+/* The following definitions come from web/cgi.c */
+
+void cgi_load_variables(FILE *f1);
+const char *cgi_variable(const char *name);
+BOOL am_root(void);
+char *cgi_user_name(void);
+void cgi_setup(const char *rootdir, int auth_required);
+const char *cgi_baseurl(void);
+const char *cgi_pathinfo(void);
+char *cgi_remote_host(void);
+char *cgi_remote_addr(void);
+BOOL cgi_waspost(void);
+
+/* The following definitions come from web/diagnose.c */
+
+BOOL nmbd_running(void);
+BOOL smbd_running(void);
+
+/* The following definitions come from web/startstop.c */
+
+void start_smbd(void);
+void start_nmbd(void);
+void stop_smbd(void);
+void stop_nmbd(void);
+void kill_pid(pid_t pid);
+
+/* The following definitions come from web/statuspage.c */
+
+void status_page(void);
+
+/* The following definitions come from web/swat.c */
+
+#endif /* _PROTO_H_ */
diff --git a/jerry2/source/include/version.h b/jerry2/source/include/version.h
new file mode 100755
index 00000000000..5159d908f19
--- /dev/null
+++ b/jerry2/source/include/version.h
@@ -0,0 +1 @@
+#define VERSION "2.2.10"
diff --git a/jerry2/source/smbd/filename.c b/jerry2/source/smbd/filename.c
new file mode 100644
index 00000000000..c94fddf931f
--- /dev/null
+++ b/jerry2/source/smbd/filename.c
@@ -0,0 +1,506 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ filename handling routines
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1999-200
+ Copyright (C) Ying Chen 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * New hash table stat cache code added by Ying Chen.
+ */
+
+#include "includes.h"
+
+extern BOOL case_sensitive;
+extern BOOL case_preserve;
+extern BOOL short_case_preserve;
+extern fstring remote_machine;
+extern BOOL use_mangled_map;
+
+static BOOL scan_directory(const char *path, char *name,size_t maxlength,
+ connection_struct *conn,BOOL docache);
+
+/****************************************************************************
+ Check if two filenames are equal.
+ This needs to be careful about whether we are case sensitive.
+****************************************************************************/
+
+static BOOL fname_equal(char *name1, char *name2)
+{
+ /* Normal filename handling */
+ if (case_sensitive)
+ return(strcmp(name1,name2) == 0);
+
+ return(strequal(name1,name2));
+}
+
+/****************************************************************************
+ Mangle the 2nd name and check if it is then equal to the first name.
+****************************************************************************/
+
+static BOOL mangled_equal(char *name1, const char *name2, int snum)
+{
+ pstring tmpname;
+
+ pstrcpy(tmpname,name2);
+ mangle_map(tmpname,True,False,snum);
+ return strequal(name1,tmpname);
+}
+
+/****************************************************************************
+This routine is called to convert names from the dos namespace to unix
+namespace. It needs to handle any case conversions, mangling, format
+changes etc.
+
+We assume that we have already done a chdir() to the right "root" directory
+for this service.
+
+The function will return False if some part of the name except for the last
+part cannot be resolved
+
+If the saved_last_component != 0, then the unmodified last component
+of the pathname is returned there. This is used in an exceptional
+case in reply_mv (so far). If saved_last_component == 0 then nothing
+is returned there.
+
+The bad_path arg is set to True if the filename walk failed. This is
+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.
+
+On exit from unix_convert, if *pst was not null, then the file stat
+struct will be returned if the file exists and was found, if not this
+stat struct will be filled with zeros (and this can be detected by checking
+for nlinks = 0, which can never be true for any file).
+****************************************************************************/
+
+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;
+ BOOL component_was_mangled = False;
+ BOOL name_has_wildcard = False;
+#if 0
+ /* Andrew's conservative code... JRA. */
+ extern char magic_char;
+#endif
+
+ ZERO_STRUCTP(pst);
+
+ *dirpath = 0;
+ *bad_path = False;
+ if(saved_last_component)
+ *saved_last_component = 0;
+
+ if (conn->printer) {
+ /* we don't ever use the filenames on a printer share as a
+ filename - so don't convert them */
+ return True;
+ }
+
+ DEBUG(5, ("unix_convert called on file \"%s\"\n", name));
+
+ /*
+ * Convert to basic unix format - removing \ chars and cleaning it up.
+ */
+
+ unix_format(name);
+ unix_clean_name(name);
+
+ /*
+ * Names must be relative to the root of the service - trim any leading /.
+ * also trim trailing /'s.
+ */
+
+ trim_string(name,"/","/");
+
+ /*
+ * If we trimmed down to a single '\0' character
+ * then we should use the "." directory to avoid
+ * searching the cache, but not if we are in a
+ * printing share.
+ */
+
+ if (!*name) {
+ name[0] = '.';
+ name[1] = '\0';
+ }
+
+ /*
+ * Ensure saved_last_component is valid even if file exists.
+ */
+
+ if(saved_last_component) {
+ end = strrchr(name, '/');
+ if(end)
+ pstrcpy(saved_last_component, end + 1);
+ else
+ pstrcpy(saved_last_component, name);
+ }
+
+ if (!case_sensitive && (!case_preserve || (mangle_is_8_3(name, False) && !short_case_preserve)))
+ strnorm(name);
+
+ /*
+ * If we trimmed down to a single '\0' character
+ * then we will be using the "." directory.
+ * As we know this is valid we can return true here.
+ */
+
+ if(!*name)
+ return(True);
+
+ start = name;
+ while (strncmp(start,"./",2) == 0)
+ start += 2;
+
+ pstrcpy(orig_path, name);
+
+ if(stat_cache_lookup(conn, name, dirpath, &start, &st)) {
+ *pst = st;
+ return True;
+ }
+
+ /*
+ * stat the name - if it exists then we are all done!
+ */
+
+ if (vfs_stat(conn,name,&st) == 0) {
+ stat_cache_add(orig_path, name);
+ DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
+ *pst = st;
+ return(True);
+ }
+
+ DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n", name, dirpath, start));
+
+ /*
+ * A special case - if we don't have any mangling chars and are case
+ * sensitive then searching won't help.
+ */
+
+ if (case_sensitive && !mangle_is_mangled(name) && !use_mangled_map)
+ return(False);
+
+ name_has_wildcard = ms_has_wild(start);
+
+ /*
+ * is_mangled() was changed to look at an entire pathname, not
+ * just a component. JRA.
+ */
+
+ if(mangle_is_mangled(start))
+ component_was_mangled = True;
+
+ /*
+ * Now we need to recursively match the name against the real
+ * directory structure.
+ */
+
+ /*
+ * Match each part of the path name separately, trying the names
+ * as is first, then trying to scan the directory for matching names.
+ */
+
+ for (; start ; start = (end?end+1:(char *)NULL)) {
+ /*
+ * Pinpoint the end of this section of the filename.
+ */
+ end = strchr(start, '/');
+
+ /*
+ * Chop the name at this point.
+ */
+ if (end)
+ *end = 0;
+
+ if(saved_last_component != 0)
+ pstrcpy(saved_last_component, end ? end + 1 : start);
+
+ /*
+ * Check if the name exists up to this point.
+ */
+
+ if (vfs_stat(conn,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.
+ */
+ if (end && !(st.st_mode & S_IFDIR)) {
+ /*
+ * An intermediate part of the name isn't a directory.
+ */
+ DEBUG(5,("Not a dir %s\n",start));
+ *end = '/';
+ return(False);
+ }
+
+ } else {
+ pstring rest;
+
+ /* Stat failed - ensure we don't use it. */
+ ZERO_STRUCT(st);
+ *rest = 0;
+
+ /*
+ * Remember the rest of the pathname so it can be restored
+ * later.
+ */
+
+ if (end)
+ pstrcpy(rest,end+1);
+
+ /*
+ * Try to find this part of the path in the directory.
+ */
+
+ if (ms_has_wild(start) ||
+ !scan_directory(dirpath, start,
+ sizeof(pstring) - 1 - (start - name),
+ conn,
+ end?True:False)) {
+ if (end) {
+ /*
+ * An intermediate part of the name can't be found.
+ */
+ DEBUG(5,("Intermediate not found %s\n",start));
+ *end = '/';
+
+ /*
+ * We need to return the fact that the intermediate
+ * name resolution failed. This is used to return an
+ * error of ERRbadpath rather than ERRbadfile. Some
+ * Windows applications depend on the difference between
+ * these two errors.
+ */
+ *bad_path = True;
+ return(False);
+ }
+
+ /*
+ * Just the last part of the name doesn't exist.
+ * We may need to strupper() or strlower() it in case
+ * this conversion is being used for file creation
+ * purposes. If the filename is of mixed case then
+ * don't normalise it.
+ */
+
+ if (!case_preserve && (!strhasupper(start) || !strhaslower(start)))
+ strnorm(start);
+
+ /*
+ * check on the mangled stack to see if we can recover the
+ * base of the filename.
+ */
+
+ if (mangle_is_mangled(start)) {
+ mangle_check_cache( start, sizeof(pstring) - 1 - (start - name) );
+ }
+
+ DEBUG(5,("New file %s\n",start));
+ return(True);
+ }
+
+ /*
+ * Restore the rest of the string. If the string was mangled the size
+ * may have changed.
+ */
+ if (end) {
+ end = start + strlen(start);
+ if (!safe_strcat(start, "/", sizeof(pstring) - 1 - (start - name)) ||
+ !safe_strcat(start, rest, sizeof(pstring) - 1 - (start - name))) {
+ return False;
+ }
+ *end = '\0';
+ } else {
+ /*
+ * We just scanned for, and found the end of the path.
+ * We must return a valid stat struct if it exists.
+ * JRA.
+ */
+
+ if (vfs_stat(conn,name, &st) == 0) {
+ *pst = st;
+ } else {
+ ZERO_STRUCT(st);
+ }
+ }
+ } /* end else */
+
+ /*
+ * Add to the dirpath that we have resolved so far.
+ */
+ if (*dirpath)
+ pstrcat(dirpath,"/");
+
+ pstrcat(dirpath,start);
+
+ /*
+ * Don't cache a name with mangled or wildcard components
+ * as this can change the size.
+ */
+
+ if(!component_was_mangled && !name_has_wildcard)
+ stat_cache_add(orig_path, dirpath);
+
+ /*
+ * Restore the / that we wiped out earlier.
+ */
+ if (end)
+ *end = '/';
+ }
+
+ /*
+ * Don't cache a name with mangled or wildcard components
+ * as this can change the size.
+ */
+
+ if(!component_was_mangled && !name_has_wildcard)
+ stat_cache_add(orig_path, name);
+
+ /*
+ * If we ended up resolving the entire path then return a valid
+ * stat struct if we got one.
+ */
+
+ if (VALID_STAT(st) && (strlen(orig_path) == strlen(name)))
+ *pst = st;
+
+ /*
+ * The name has been resolved.
+ */
+
+ DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
+ return(True);
+}
+
+/****************************************************************************
+ Check a filename - possibly caling reducename.
+ This is called by every routine before it allows an operation on a filename.
+ It does any final confirmation necessary to ensure that the filename is
+ a valid one for the user to access.
+****************************************************************************/
+
+BOOL check_name(char *name,connection_struct *conn)
+{
+ BOOL ret;
+
+ errno = 0;
+
+ if(IS_VETO_PATH(conn, name)) {
+ if(strcmp(name, ".") && strcmp(name, "..")) {
+ DEBUG(5,("file path name %s vetoed\n",name));
+ return(0);
+ }
+ }
+
+ ret = reduce_name(conn,name,conn->connectpath,lp_widelinks(SNUM(conn)));
+
+ /* Check if we are allowing users to follow symlinks */
+ /* Patch from David Clerc <David.Clerc@cui.unige.ch>
+ University of Geneva */
+
+#ifdef S_ISLNK
+ if (!lp_symlinks(SNUM(conn))) {
+ SMB_STRUCT_STAT statbuf;
+ if ( (conn->vfs_ops.lstat(conn,dos_to_unix_static(name),&statbuf) != -1) &&
+ (S_ISLNK(statbuf.st_mode)) ) {
+ DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
+ ret=0;
+ }
+ }
+#endif
+
+ if (!ret)
+ DEBUG(5,("check_name on %s failed\n",name));
+
+ return(ret);
+}
+
+/****************************************************************************
+ Scan a directory to find a filename, matching without case sensitivity.
+ If the name looks like a mangled name then try via the mangling functions
+****************************************************************************/
+
+static BOOL scan_directory(const char *path, char *name,size_t maxlength,
+ connection_struct *conn,BOOL docache)
+{
+ void *cur_dir;
+ char *dname;
+ BOOL mangled;
+
+ mangled = mangle_is_mangled(name);
+
+ /* handle null paths */
+ if (*path == 0)
+ path = ".";
+
+ if (docache && (dname = DirCacheCheck(path,name,SNUM(conn)))) {
+ safe_strcpy(name, dname, maxlength);
+ return(True);
+ }
+
+ /*
+ * The incoming name can be mangled, and if we de-mangle it
+ * here it will not compare correctly against the filename (name2)
+ * read from the directory and then mangled by the name_map_mangle()
+ * call. We need to mangle both names or neither.
+ * (JRA).
+ */
+ if (mangled)
+ mangled = !mangle_check_cache( name, maxlength );
+
+ /* open the directory */
+ if (!(cur_dir = OpenDir(conn, path, True))) {
+ DEBUG(3,("scan dir didn't open dir [%s]\n",path));
+ return(False);
+ }
+
+ /* now scan for matching names */
+ while ((dname = ReadDirName(cur_dir))) {
+ if (*dname == '.' && (strequal(dname,".") || strequal(dname,"..")))
+ continue;
+
+ /*
+ * At this point dname is the unmangled name.
+ * name is either mangled or not, depending on the state of the "mangled"
+ * variable. JRA.
+ */
+
+ /*
+ * Check mangled name against mangled name, or unmangled name
+ * against unmangled name.
+ */
+
+ if ((mangled && mangled_equal(name,dname,SNUM(conn))) || fname_equal(name, dname)) {
+ /* we've found the file, change it's name and return */
+ if (docache)
+ DirCacheAdd(path,name,dname,SNUM(conn));
+ safe_strcpy(name, dname, maxlength);
+ CloseDir(cur_dir);
+ return(True);
+ }
+ }
+
+ CloseDir(cur_dir);
+ return(False);
+}
diff --git a/jerry2/source/smbd/mangle.c b/jerry2/source/smbd/mangle.c
new file mode 100644
index 00000000000..d108cbf4b19
--- /dev/null
+++ b/jerry2/source/smbd/mangle.c
@@ -0,0 +1,123 @@
+/*
+ Unix SMB/CIFS implementation.
+ Name mangling interface
+ Copyright (C) Andrew Tridgell 2002
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+static struct mangle_fns *mangle_fns;
+
+/* this allows us to add more mangling backends */
+static struct {
+ const char *name;
+ struct mangle_fns *(*init_fn)(void);
+} mangle_backends[] = {
+ { "hash", mangle_hash_init },
+ { "hash2", mangle_hash2_init },
+ { NULL, NULL }
+};
+
+/*
+ initialise the mangling subsystem
+*/
+static void mangle_init(void)
+{
+ int i;
+ char *method;
+
+ if (mangle_fns)
+ return;
+
+ method = lp_mangling_method();
+
+ /* find the first mangling method that manages to initialise and
+ matches the "mangling method" parameter */
+ for (i=0; mangle_backends[i].name && !mangle_fns; i++) {
+ if (!method || !*method || strcmp(method, mangle_backends[i].name) == 0) {
+ mangle_fns = mangle_backends[i].init_fn();
+ }
+ }
+
+ if (!mangle_fns) {
+ DEBUG(0,("Failed to initialise mangling system '%s'\n", method));
+ exit_server("mangling init failed");
+ }
+}
+
+
+/*
+ reset the cache. This is called when smb.conf has been reloaded
+*/
+void mangle_reset_cache(void)
+{
+ mangle_init();
+
+ mangle_fns->reset();
+}
+
+/*
+ see if a filename has come out of our mangling code
+*/
+BOOL mangle_is_mangled(const char *s)
+{
+ return mangle_fns->is_mangled(s);
+}
+
+/*
+ see if a filename matches the rules of a 8.3 filename
+*/
+BOOL mangle_is_8_3(const char *fname, BOOL check_case)
+{
+ return mangle_fns->is_8_3(fname, check_case, False);
+}
+
+BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case)
+{
+ return mangle_fns->is_8_3(fname, check_case, True);
+}
+
+/*
+ try to reverse map a 8.3 name to the original filename. This doesn't have to
+ always succeed, as the directory handling code in smbd will scan the directory
+ looking for a matching name if it doesn't. It should succeed most of the time
+ or there will be a huge performance penalty
+*/
+BOOL mangle_check_cache(char *s, size_t maxlen)
+{
+ return mangle_fns->check_cache(s, maxlen);
+}
+
+/*
+ map a long filename to a 8.3 name.
+ */
+
+void mangle_map(char *OutName, BOOL need83, BOOL cache83, int snum)
+{
+ /* name mangling can be disabled for speed, in which case
+ we just truncate the string */
+ if (!lp_manglednames(snum)) {
+ if (need83) {
+ string_truncate(OutName, 12);
+ }
+ return;
+ }
+
+ /* invoke the inane "mangled map" code */
+ mangle_map_filename(OutName, snum);
+ mangle_fns->name_map(OutName, need83, cache83);
+}
diff --git a/jerry2/source/smbd/mangle_hash.c b/jerry2/source/smbd/mangle_hash.c
new file mode 100644
index 00000000000..b09889fc03e
--- /dev/null
+++ b/jerry2/source/smbd/mangle_hash.c
@@ -0,0 +1,880 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Name mangling
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* -------------------------------------------------------------------------- **
+ * Notable problems...
+ *
+ * March/April 1998 CRH
+ * - Many of the functions in this module overwrite string buffers passed to
+ * them. This causes a variety of problems and is, generally speaking,
+ * dangerous and scarry. See the kludge notes in name_map_mangle()
+ * below.
+ * - It seems that something is calling name_map_mangle() twice. The
+ * first call is probably some sort of test. Names which contain
+ * illegal characters are being doubly mangled. I'm not sure, but
+ * I'm guessing the problem is in server.c.
+ *
+ * -------------------------------------------------------------------------- **
+ */
+
+/* -------------------------------------------------------------------------- **
+ * History...
+ *
+ * March/April 1998 CRH
+ * Updated a bit. Rewrote is_mangled() to be a bit more selective.
+ * Rewrote the mangled name cache. Added comments here and there.
+ * &c.
+ * -------------------------------------------------------------------------- **
+ */
+
+#include "includes.h"
+
+
+/* -------------------------------------------------------------------------- **
+ * External Variables...
+ */
+
+extern int case_default; /* Are conforming 8.3 names all upper or lower? */
+extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */
+
+/* -------------------------------------------------------------------------- **
+ * Other stuff...
+ *
+ * magic_char - This is the magic char used for mangling. It's
+ * global. There is a call to lp_magicchar() in server.c
+ * that is used to override the initial value.
+ *
+ * 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).
+ *
+ * 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
+ * two nibble pair. See BASECHAR_MASK and ILLEGAL_MASK,
+ * below.
+ *
+ * ct_initialized - False until the chartest array has been initialized via
+ * a call to init_chartest().
+ *
+ * BASECHAR_MASK - Masks the upper nibble of a one-byte value.
+ *
+ * ILLEGAL_MASK - Masks the lower nibble of a one-byte value.
+ *
+ * isbasecahr() - Given a character, check the chartest array to see
+ * if that character is in the basechars set. This is
+ * faster than using strchr().
+ *
+ * isillegal() - Given a character, check the chartest array to see
+ * if that character is in the illegal characters set.
+ * This is faster than using strchr().
+ *
+ * mangled_cache - Cache header used for storing mangled -> original
+ * reverse maps.
+ *
+ * mc_initialized - False until the mangled_cache structure has been
+ * initialized via a call to reset_mangled_cache().
+ *
+ * MANGLED_CACHE_MAX_ENTRIES - Default maximum number of entries for the
+ * cache. A value of 0 indicates "infinite".
+ *
+ * MANGLED_CACHE_MAX_MEMORY - Default maximum amount of memory for the
+ * cache. When the cache was kept as an array of 256
+ * byte strings, the default cache size was 50 entries.
+ * This required a fixed 12.5Kbytes of memory. The
+ * mangled stack parameter is no longer used (though
+ * this might change). We're now using a fixed 16Kbyte
+ * maximum cache size. This will probably be much more
+ * than 50 entries.
+ */
+
+char magic_char = '~';
+
+static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
+#define MANGLE_BASE (sizeof(basechars)/sizeof(char)-1)
+
+static unsigned char chartest[256] = { 0 };
+static BOOL ct_initialized = False;
+
+#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
+#define BASECHAR_MASK 0xf0
+#define ILLEGAL_MASK 0x0f
+#define isbasechar(C) ( (chartest[ ((C) & 0xff) ]) & BASECHAR_MASK )
+#define isillegal(C) ( (chartest[ ((C) & 0xff) ]) & ILLEGAL_MASK )
+
+static ubi_cacheRoot mangled_cache[1] = { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0 } };
+static BOOL mc_initialized = False;
+#define MANGLED_CACHE_MAX_ENTRIES 1024
+#define MANGLED_CACHE_MAX_MEMORY 0
+
+
+/* -------------------------------------------------------------------------- **
+ * Functions...
+ */
+
+/* ************************************************************************** **
+ * Initialize the static character test array.
+ *
+ * Input: none
+ *
+ * Output: none
+ *
+ * Notes: This function changes (loads) the contents of the <chartest>
+ * array. The scope of <chartest> is this file.
+ *
+ * ************************************************************************** **
+ */
+static void init_chartest( void )
+ {
+ const char *illegalchars = "*\\/?<>|\":";
+ const unsigned char *s;
+
+ memset( (char *)chartest, '\0', 256 );
+
+ for( s = (const unsigned char *)illegalchars; *s; s++ )
+ chartest[*s] = ILLEGAL_MASK;
+
+ for( s = (const unsigned char *)basechars; *s; s++ )
+ chartest[*s] |= BASECHAR_MASK;
+
+ ct_initialized = True;
+ } /* init_chartest */
+
+/* ************************************************************************** **
+ * Return True if a name is a special msdos reserved name.
+ *
+ * Input: fname - String containing the name to be tested.
+ *
+ * Output: True, if the name matches one of the list of reserved names.
+ *
+ * Notes: This is a static function called by is_8_3(), below.
+ *
+ * ************************************************************************** **
+ */
+static BOOL is_reserved_msdos( const char *fname )
+ {
+ char upperFname[13];
+ char *p;
+
+ StrnCpy (upperFname, fname, 12);
+
+ /* lpt1.txt and con.txt etc are also illegal */
+ p = strchr(upperFname,'.');
+ if( p )
+ *p = '\0';
+
+ strupper( upperFname );
+ p = upperFname + 1;
+ switch( upperFname[0] )
+ {
+ case 'A':
+ if( 0 == strcmp( p, "UX" ) )
+ return( True );
+ break;
+ case 'C':
+ if( (0 == strcmp( p, "LOCK$" ))
+ || (0 == strcmp( p, "ON" ))
+ || (0 == strcmp( p, "OM1" ))
+ || (0 == strcmp( p, "OM2" ))
+ || (0 == strcmp( p, "OM3" ))
+ || (0 == strcmp( p, "OM4" ))
+ )
+ return( True );
+ break;
+ case 'L':
+ if( (0 == strcmp( p, "PT1" ))
+ || (0 == strcmp( p, "PT2" ))
+ || (0 == strcmp( p, "PT3" ))
+ )
+ return( True );
+ break;
+ case 'N':
+ if( 0 == strcmp( p, "UL" ) )
+ return( True );
+ break;
+ case 'P':
+ if( 0 == strcmp( p, "RN" ) )
+ return( True );
+ break;
+ }
+
+ return( False );
+ } /* is_reserved_msdos */
+
+/* ************************************************************************** **
+ * Determine whether or not a given name contains illegal characters, even
+ * long names.
+ *
+ * Input: name - The name to be tested.
+ *
+ * Output: True if an illegal character was found in <name>, else False.
+ *
+ * Notes: This is used to test a name on the host system, long or short,
+ * for characters that would be illegal on most client systems,
+ * particularly DOS and Windows systems. Unix and AmigaOS, for
+ * example, allow a filenames which contain such oddities as
+ * quotes ("). If a name is found which does contain an illegal
+ * character, it is mangled even if it conforms to the 8.3
+ * format.
+ *
+ * ************************************************************************** **
+ */
+static BOOL is_illegal_name( char *name )
+ {
+ unsigned char *s;
+ int skip;
+ int namelen;
+
+ if( !name )
+ return( True );
+
+ if( !ct_initialized )
+ init_chartest();
+
+ namelen = strlen(name);
+ if (namelen &&
+ name[namelen-1] == '.' &&
+ !strequal(name, ".") &&
+ !strequal(name, ".."))
+ return True;
+
+ s = (unsigned char *)name;
+ while( *s )
+ {
+ skip = get_character_len( *s );
+ if( skip != 0 )
+ {
+ s += skip;
+ }
+ else
+ {
+ if( isillegal( *s ) )
+ return( True );
+ else
+ s++;
+ }
+ }
+
+ return( False );
+ } /* is_illegal_name */
+
+/* ************************************************************************** **
+ * Return True if the name *could be* a mangled name.
+ *
+ * Input: s - A path name - in UNIX pathname format.
+ *
+ * Output: True if the name matches the pattern described below in the
+ * notes, else False.
+ *
+ * Notes: The input name is *not* tested for 8.3 compliance. This must be
+ * done separately. This function returns true if the name contains
+ * a magic character followed by excactly two characters from the
+ * basechars list (above), which in turn are followed either by the
+ * nul (end of string) byte or a dot (extension) or by a '/' (end of
+ * a directory name).
+ *
+ * ************************************************************************** **
+ */
+static BOOL is_mangled( const char *s )
+{
+ char *magic;
+ BOOL ret = False;
+
+ if( !ct_initialized )
+ init_chartest();
+
+ magic = strchr( s, magic_char );
+ while( magic && magic[1] && magic[2] ) {
+ /* 3 chars, 1st is magic. */
+ if( ('.' == magic[3] || '/' == magic[3] || !(magic[3])) /* Ends with '.' or nul or '/' ? */
+ && isbasechar( toupper(magic[1]) ) /* is 2nd char basechar? */
+ && isbasechar( toupper(magic[2]) ) ) /* is 3rd char basechar? */
+ ret = ( True ); /* If all above, then true, */
+ magic = strchr( magic+1, magic_char ); /* else seek next magic. */
+ }
+
+ DEBUG(10,("is_mangled: %s : %s\n", s, ret ? "True" : "False"));
+
+ return ret;
+} /* is_mangled */
+
+static BOOL is_ms_wildchar(const char c)
+{
+ switch(c) {
+ case '*':
+ case '?':
+ case '<':
+ case '>':
+ case '"':
+ return True;
+ default:
+ return False;
+ }
+}
+
+/* ************************************************************************** **
+ * Return True if the name is a valid DOS name in 8.3 DOS format.
+ *
+ * Input: fname - File name to be checked.
+ * check_case - If True, and if case_mangle is True, then the
+ * name will be checked to see if all characters
+ * are the correct case. See case_mangle and
+ * case_default above.
+ * allow_wildcards - If True dos wildcard characters *?<>" are allowed as 8.3.
+ *
+ * Output: True if the name is a valid DOS name, else False.
+ *
+ * ************************************************************************** **
+ */
+
+static BOOL is_8_3( const char *cfname, BOOL check_case, BOOL allow_wildcards )
+{
+ int len;
+ int l;
+ int skip;
+ const char *p;
+ const char *dot_pos;
+ char *slash_pos;
+ const char *fname = cfname;
+
+ slash_pos = strrchr( fname, '/' );
+
+ /* If there is a directory path, skip it. */
+ if( slash_pos )
+ fname = slash_pos + 1;
+ len = strlen( fname );
+
+ DEBUG( 5, ( "Checking %s for 8.3\n", fname ) );
+
+ /* Can't be 0 chars or longer than 12 chars */
+ if( (len == 0) || (len > 12) )
+ return( False );
+
+ /* Mustn't be an MS-DOS Special file such as lpt1 or even lpt1.txt */
+ if( is_reserved_msdos( fname ) )
+ return( False );
+
+ /* Check that all characters are the correct case, if asked to do so. */
+ if( check_case && case_mangle ) {
+ switch( case_default ) {
+ case CASE_LOWER:
+ if( strhasupper( fname ) )
+ return(False);
+ break;
+ case CASE_UPPER:
+ if( strhaslower( fname ) )
+ return(False);
+ break;
+ }
+ }
+
+ /* Can't contain invalid dos chars */
+ /* Windows use the ANSI charset.
+ But filenames are translated in the PC charset.
+ This Translation may be more or less relaxed depending
+ the Windows application. */
+
+ /* %%% A nice improvment to name mangling would be to translate
+ filename to ANSI charset on the smb server host */
+
+ p = fname;
+ dot_pos = NULL;
+ while( *p ) {
+ if( (skip = get_character_len( *p )) != 0 )
+ p += skip;
+ else {
+ if( *p == '.' && !dot_pos )
+ dot_pos = p;
+ else {
+ if( !isdoschar( *p )) {
+ if (!allow_wildcards)
+ return False;
+ if (!is_ms_wildchar(*p))
+ return False;
+ }
+ }
+ p++;
+ }
+ }
+
+ /* no dot and less than 9 means OK */
+ if( !dot_pos )
+ return( len <= 8 );
+
+ l = PTR_DIFF( dot_pos, fname );
+
+ /* base must be at least 1 char except special cases . and .. */
+ if( l == 0 )
+ return( 0 == strcmp( fname, "." ) || 0 == strcmp( fname, ".." ) );
+
+ /* base can't be greater than 8 */
+ if( l > 8 )
+ return( False );
+
+ /* extension must be between 1 and 3 */
+ if( (len - l < 2 ) || (len - l > 4) )
+ return( False );
+
+ /* extensions may not have a dot */
+ if( strchr( dot_pos+1, '.' ) )
+ return( False );
+
+ /* must be in 8.3 format */
+ return( True );
+}
+
+/* ************************************************************************** **
+ * Compare two cache keys and return a value indicating their ordinal
+ * relationship.
+ *
+ * Input: ItemPtr - Pointer to a comparison key. In this case, this will
+ * be a mangled name string.
+ * NodePtr - Pointer to a node in the cache. The node structure
+ * will be followed in memory by a mangled name string.
+ *
+ * Output: A signed integer, as follows:
+ * (x < 0) <==> Key1 less than Key2
+ * (x == 0) <==> Key1 equals Key2
+ * (x > 0) <==> Key1 greater than Key2
+ *
+ * Notes: This is a ubiqx-style comparison routine. See ubi_BinTree for
+ * more info.
+ *
+ * ************************************************************************** **
+ */
+
+static signed int cache_compare( ubi_btItemPtr ItemPtr, ubi_btNodePtr NodePtr )
+{
+ char *Key1 = (char *)ItemPtr;
+ char *Key2 = (char *)(((ubi_cacheEntryPtr)NodePtr) + 1);
+
+ DEBUG(100,("cache_compare: %s %s\n", Key1, Key2));
+
+ return( StrCaseCmp( Key1, Key2 ) );
+}
+
+/* ************************************************************************** **
+ * Free a cache entry.
+ *
+ * Input: WarrenZevon - Pointer to the entry that is to be returned to
+ * Nirvana.
+ * Output: none.
+ *
+ * Notes: This function gets around the possibility that the standard
+ * free() function may be implemented as a macro, or other evil
+ * subversions (oh, so much fun).
+ *
+ * ************************************************************************** **
+ */
+
+static void cache_free_entry( ubi_trNodePtr WarrenZevon )
+{
+ ZERO_STRUCTP(WarrenZevon);
+ SAFE_FREE( WarrenZevon );
+}
+
+/* ************************************************************************** **
+ * Initializes or clears the mangled cache.
+ *
+ * Input: none.
+ * Output: none.
+ *
+ * Notes: There is a section below that is commented out. It shows how
+ * one might use lp_ calls to set the maximum memory and entry size
+ * of the cache. You might also want to remove the constants used
+ * in ubi_cacheInit() and replace them with lp_ calls. If so, then
+ * the calls to ubi_cacheSetMax*() would be moved into the else
+ * clause. Another option would be to pass in the max_entries and
+ * max_memory values as parameters. crh 09-Apr-1998.
+ *
+ * ************************************************************************** **
+ */
+
+static void reset_mangled_cache( void )
+{
+ if( !mc_initialized ) {
+ (void)ubi_cacheInit( mangled_cache,
+ cache_compare,
+ cache_free_entry,
+ MANGLED_CACHE_MAX_ENTRIES,
+ MANGLED_CACHE_MAX_MEMORY );
+ mc_initialized = True;
+ } else {
+ (void)ubi_cacheClear( mangled_cache );
+ }
+
+ /*
+ (void)ubi_cacheSetMaxEntries( mangled_cache, lp_mangled_cache_entries() );
+ (void)ubi_cacheSetMaxMemory( mangled_cache, lp_mangled_cache_memory() );
+ */
+}
+
+/* ************************************************************************** **
+ * Add a mangled name into the cache.
+ *
+ * Notes: If the mangled cache has not been initialized, then the
+ * function will simply fail. It could initialize the cache,
+ * but that's not the way it was done before I changed the
+ * cache mechanism, so I'm sticking with the old method.
+ *
+ * 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 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:
+ *
+ * - the extension must exist on the raw name,
+ * - it must be all lower case
+ * - it must match the mangled extension (to prove that no
+ * mangling occurred).
+ *
+ * crh 07-Apr-1998
+ *
+ * ************************************************************************** **
+ */
+static void cache_mangled_name( char *mangled_name, char *raw_name )
+{
+ ubi_cacheEntryPtr new_entry;
+ char *s1;
+ char *s2;
+ size_t mangled_len;
+ size_t raw_len;
+ size_t i;
+
+ /* If the cache isn't initialized, give up. */
+ if( !mc_initialized )
+ return;
+
+ /* Init the string lengths. */
+ mangled_len = strlen( mangled_name );
+ raw_len = strlen( raw_name );
+
+ /* See if the extensions are unmangled. If so, store the entry
+ * without the extension, thus creating a "group" reverse map.
+ */
+ s1 = strrchr( mangled_name, '.' );
+ if( s1 && (s2 = strrchr( raw_name, '.' )) )
+ {
+ i = 1;
+ while( s1[i] && (tolower( s1[i] ) == s2[i]) )
+ i++;
+ if( !s1[i] && !s2[i] )
+ {
+ mangled_len -= i;
+ raw_len -= i;
+ }
+ }
+
+ /* 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 )
+ return;
+
+ /* Fill the new cache entry, and add it to the cache. */
+ s1 = (char *)(new_entry + 1);
+ s2 = (char *)&(s1[mangled_len + 1]);
+ (void)StrnCpy( s1, mangled_name, mangled_len );
+ (void)StrnCpy( s2, raw_name, raw_len );
+ ubi_cachePut( mangled_cache, i, new_entry, s1 );
+}
+
+/* ************************************************************************** **
+ * Check for a name on the mangled name stack
+ *
+ * Input: s - Input *and* output string buffer.
+ *
+ * Output: True if the name was found in the cache, else False.
+ *
+ * Notes: If a reverse map is found, the function will overwrite the string
+ * space indicated by the input pointer <s>. This is frightening.
+ * It should be rewritten to return NULL if the long name was not
+ * found, and a pointer to the long name if it was found.
+ *
+ * ************************************************************************** **
+ */
+
+static BOOL check_mangled_cache( char *s, size_t maxlen )
+{
+ 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 )
+ return( False );
+
+ FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)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 );
+ /*
+ * 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)safe_strcat( s, saved_ext, maxlen );
+ SAFE_FREE(saved_ext);
+ }
+ return( False );
+ }
+
+ /* If we *did* find it, we need to copy it into the string buffer. */
+ found_name = (char *)(FoundPtr + 1);
+ found_name += (strlen( found_name ) + 1);
+
+ DEBUG( 3, ("Found %s on mangled stack ", s) );
+
+ (void)safe_strcpy( s, found_name, maxlen );
+ if( saved_ext )
+ {
+ /* Replace the saved_ext as it was truncated. */
+ (void)safe_strcat( s, saved_ext,maxlen );
+ SAFE_FREE(saved_ext);
+ }
+
+ DEBUG( 3, ("as %s\n", s) );
+
+ return( True );
+}
+
+/*****************************************************************************
+ * do the actual mangling to 8.3 format
+ * the buffer must be able to hold 13 characters (including the null)
+ *****************************************************************************
+ */
+static void mangle_name_83( char *s)
+{
+ int csum;
+ char *p;
+ char extension[4];
+ char base[9];
+ int baselen = 0;
+ int extlen = 0;
+ int skip;
+
+ extension[0] = 0;
+ base[0] = 0;
+
+ p = strrchr(s,'.');
+ if( p && (strlen(p+1) < (size_t)4) )
+ {
+ BOOL all_normal = ( strisnormal(p+1) ); /* XXXXXXXXX */
+
+ if( all_normal && p[1] != 0 )
+ {
+ *p = 0;
+ csum = str_checksum( s );
+ *p = '.';
+ }
+ else
+ csum = str_checksum(s);
+ }
+ else
+ csum = str_checksum(s);
+
+ strupper( s );
+
+ DEBUG( 5, ("Mangling name %s to ",s) );
+
+ if( p )
+ {
+ if( p == s )
+ safe_strcpy( extension, "___", 3 );
+ else
+ {
+ *p++ = 0;
+ while( *p && extlen < 3 )
+ {
+ skip = get_character_len( *p );
+ switch( skip )
+ {
+ case 2:
+ if( extlen < 2 )
+ {
+ extension[extlen++] = p[0];
+ extension[extlen++] = p[1];
+ }
+ else
+ {
+ extension[extlen++] = mangle( (unsigned char)*p );
+ }
+ p += 2;
+ break;
+ case 1:
+ extension[extlen++] = p[0];
+ p++;
+ break;
+ default:
+ if( isdoschar (*p) && *p != '.' )
+ extension[extlen++] = p[0];
+ p++;
+ break;
+ }
+ }
+ extension[extlen] = 0;
+ }
+ }
+
+ p = s;
+
+ while( *p && baselen < 5 )
+ {
+ skip = get_character_len(*p);
+ switch( skip )
+ {
+ case 2:
+ if( baselen < 4 )
+ {
+ base[baselen++] = p[0];
+ base[baselen++] = p[1];
+ }
+ else
+ {
+ base[baselen++] = mangle( (unsigned char)*p );
+ }
+ p += 2;
+ break;
+ case 1:
+ base[baselen++] = p[0];
+ p++;
+ break;
+ default:
+ if( isdoschar( *p ) && *p != '.' )
+ base[baselen++] = p[0];
+ p++;
+ break;
+ }
+ }
+ base[baselen] = 0;
+
+ csum = csum % (MANGLE_BASE*MANGLE_BASE);
+
+ (void)slprintf(s, 12, "%s%c%c%c",
+ base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
+
+ if( *extension )
+ {
+ (void)pstrcat( s, "." );
+ (void)pstrcat( s, extension );
+ }
+
+ DEBUG( 5, ( "%s\n", s ) );
+
+}
+
+/*****************************************************************************
+ * Convert a filename to DOS format. Return True if successful.
+ *
+ * Input: OutName - Source *and* destination buffer.
+ *
+ * NOTE that OutName must point to a memory space that
+ * is at least 13 bytes in size!
+ *
+ * need83 - If False, name mangling will be skipped unless the
+ * name contains illegal characters. Mapping will still
+ * be done, if appropriate. This is probably used to
+ * 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.
+ *
+ * Output: Returns False only if the name wanted mangling but the share does
+ * not have name mangling turned on.
+ *
+ * ****************************************************************************
+ */
+static void name_map_mangle(char *OutName, BOOL need83, BOOL cache83)
+{
+ DEBUG(5,("name_map_mangle( %s, need83 = %s, cache83 = %s )\n", OutName,
+ need83 ? "True" : "False", cache83 ? "True" : "False" ));
+
+#ifdef MANGLE_LONG_FILENAMES
+ if( !need83 && is_illegal_name(OutName) )
+ need83 = True;
+#endif
+
+ /* check if it's already in 8.3 format */
+ if (need83 && !is_8_3(OutName, True, False)) {
+ char *tmp = NULL;
+
+ /* mangle it into 8.3 */
+ if (cache83)
+ tmp = strdup(OutName);
+
+ mangle_name_83(OutName);
+
+ if(tmp != NULL) {
+ cache_mangled_name(OutName, tmp);
+ SAFE_FREE(tmp);
+ }
+ }
+
+ DEBUG(5,("name_map_mangle() ==> [%s]\n", OutName));
+}
+
+/*
+ * the following provides the abstraction layer to make it easier
+ * to drop in an alternative mangling implementation
+ * */
+static struct mangle_fns mangle_fns = {
+ is_mangled,
+ is_8_3,
+ reset_mangled_cache,
+ check_mangled_cache,
+ name_map_mangle
+};
+
+/* return the methods for this mangling implementation */
+struct mangle_fns *mangle_hash_init(void)
+{
+ reset_mangled_cache();
+ return &mangle_fns;
+}
diff --git a/jerry2/source/smbd/mangle_hash2.c b/jerry2/source/smbd/mangle_hash2.c
new file mode 100644
index 00000000000..a218adfd61b
--- /dev/null
+++ b/jerry2/source/smbd/mangle_hash2.c
@@ -0,0 +1,661 @@
+/*
+ Unix SMB/CIFS implementation.
+ new hash based name mangling implementation
+ Copyright (C) Andrew Tridgell 2002
+ Copyright (C) Simo Sorce 2002
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ this mangling scheme uses the following format
+
+ Annnn~n.AAA
+
+ where nnnnn is a base 36 hash, and A represents characters from the original string
+
+ The hash is taken of the leading part of the long filename, in uppercase
+
+ for simplicity, we only allow ascii characters in 8.3 names
+ */
+
+ /* hash alghorithm changed to FNV1 by idra@samba.org (Simo Sorce).
+ * see http://www.isthe.com/chongo/tech/comp/fnv/index.html for a
+ * discussion on Fowler / Noll / Vo (FNV) Hash by one of it's authors
+ */
+
+/*
+ ===============================================================================
+ NOTE NOTE NOTE!!!
+
+ This file deliberately uses non-multibyte string functions in many places. This
+ is *not* a mistake. This code is multi-byte safe, but it gets this property
+ through some very subtle knowledge of the way multi-byte strings are encoded
+ and the fact that this mangling algorithm only supports ascii characters in
+ 8.3 names.
+
+ please don't convert this file to use the *_m() functions!!
+ ===============================================================================
+*/
+
+
+#include "includes.h"
+
+/* these flags are used to mark characters in as having particular
+ properties */
+#define FLAG_BASECHAR 1
+#define FLAG_ASCII 2
+#define FLAG_ILLEGAL 4
+#define FLAG_WILDCARD 8
+
+/* the "possible" flags are used as a fast way to find possible DOS
+ reserved filenames */
+#define FLAG_POSSIBLE1 16
+#define FLAG_POSSIBLE2 32
+#define FLAG_POSSIBLE3 64
+#define FLAG_POSSIBLE4 128
+
+/* by default have a max of 4096 entries in the cache. */
+#ifndef MANGLE_CACHE_SIZE
+#define MANGLE_CACHE_SIZE 4096
+#endif
+
+#define FNV1_PRIME 0x01000193
+/*the following number is a fnv1 of the string: idra@samba.org 2002 */
+#define FNV1_INIT 0xa6b93095
+
+/* these tables are used to provide fast tests for characters */
+static unsigned char char_flags[256];
+
+#define FLAG_CHECK(c, flag) (char_flags[(unsigned char)(c)] & (flag))
+
+/* we will use a very simple direct mapped prefix cache. The big
+ advantage of this cache structure is speed and low memory usage
+
+ The cache is indexed by the low-order bits of the hash, and confirmed by
+ hashing the resulting cache entry to match the known hash
+*/
+static char **prefix_cache;
+static u32 *prefix_cache_hashes;
+
+/* these are the characters we use in the 8.3 hash. Must be 36 chars long */
+static const char *basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+static unsigned char base_reverse[256];
+#define base_forward(v) basechars[v]
+
+/* the list of reserved dos names - all of these are illegal */
+static const char *reserved_names[] =
+{ "AUX", "LOCK$", "CON", "COM1", "COM2", "COM3", "COM4",
+ "LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL };
+
+/*
+ hash a string of the specified length. The string does not need to be
+ null terminated
+
+ this hash needs to be fast with a low collision rate (what hash doesn't?)
+*/
+static u32 mangle_hash(const char *key, unsigned length)
+{
+ u32 value;
+ u32 i;
+ fstring str;
+
+ /* we have to uppercase here to ensure that the mangled name
+ doesn't depend on the case of the long name. Note that this
+ is the only place where we need to use a multi-byte string
+ function */
+ strncpy(str, key, length);
+ str[length] = 0;
+ strupper(str);
+
+ /* the length of a multi-byte string can change after a strupper_m */
+ length = strlen(str);
+
+ /* Set the initial value from the key size. */
+ for (value = FNV1_INIT, i=0; i < length; i++) {
+ value *= (u32)FNV1_PRIME;
+ value ^= (u32)(str[i]);
+ }
+
+ /* note that we force it to a 31 bit hash, to keep within the limits
+ of the 36^6 mangle space */
+ return value & ~0x80000000;
+}
+
+/*
+ initialise (ie. allocate) the prefix cache
+ */
+static BOOL cache_init(void)
+{
+ if (prefix_cache) return True;
+
+ prefix_cache = calloc(MANGLE_CACHE_SIZE, sizeof(char *));
+ if (!prefix_cache) return False;
+
+ prefix_cache_hashes = calloc(MANGLE_CACHE_SIZE, sizeof(u32));
+ if (!prefix_cache_hashes) return False;
+
+ return True;
+}
+
+/*
+ insert an entry into the prefix cache. The string might not be null
+ terminated */
+static void cache_insert(const char *prefix, int length, u32 hash)
+{
+ int i = hash % MANGLE_CACHE_SIZE;
+
+ if (prefix_cache[i]) {
+ free(prefix_cache[i]);
+ }
+
+ prefix_cache[i] = strndup(prefix, length);
+ prefix_cache_hashes[i] = hash;
+}
+
+/*
+ lookup an entry in the prefix cache. Return NULL if not found.
+*/
+static const char *cache_lookup(u32 hash)
+{
+ int i = hash % MANGLE_CACHE_SIZE;
+
+ if (!prefix_cache[i] || hash != prefix_cache_hashes[i]) {
+ return NULL;
+ }
+
+ /* yep, it matched */
+ return prefix_cache[i];
+}
+
+
+/*
+ determine if a string is possibly in a mangled format, ignoring
+ case
+
+ In this algorithm, mangled names use only pure ascii characters (no
+ multi-byte) so we can avoid doing a UCS2 conversion
+ */
+static BOOL is_mangled_component(const char *name)
+{
+ int len, i;
+
+ DEBUG(10,("is_mangled_component %s ?\n", name));
+
+ /* check the length */
+ len = strlen(name);
+ if (len > 12 || len < 8) return False;
+
+ /* the best distinguishing characteristic is the ~ */
+ if (len > 7 && name[6] != '~') return False;
+
+ /* check extension */
+ if (len > 8) {
+ if (name[8] != '.') return False;
+ for (i=9; name[i]; i++) {
+ if (! FLAG_CHECK(name[i], FLAG_ASCII)) {
+ return False;
+ }
+ }
+ }
+
+ /* check first character */
+ if (! FLAG_CHECK(name[0], FLAG_ASCII)) {
+ return False;
+ }
+
+ /* check rest of hash */
+ if (! FLAG_CHECK(name[7], FLAG_BASECHAR)) {
+ return False;
+ }
+ for (i=1;i<6;i++) {
+ if (! FLAG_CHECK(name[i], FLAG_BASECHAR)) {
+ return False;
+ }
+ }
+
+ DEBUG(10,("is_mangled %s -> yes\n", name));
+
+ return True;
+}
+
+
+
+/*
+ determine if a string is possibly in a mangled format, ignoring
+ case
+
+ In this algorithm, mangled names use only pure ascii characters (no
+ multi-byte) so we can avoid doing a UCS2 conversion
+
+ NOTE! This interface must be able to handle a path with unix
+ directory separators. It should return true if any component is
+ mangled
+ */
+static BOOL is_mangled(const char *name)
+{
+ const char *p;
+ const char *s;
+
+ DEBUG(10,("is_mangled %s ?\n", name));
+
+ for (s=name; (p=strchr(s, '/')); s=p+1) {
+ char *component = strndup(s, PTR_DIFF(p, s));
+ if (is_mangled_component(component)) {
+ free(component);
+ return True;
+ }
+ free(component);
+ }
+
+ /* and the last part ... */
+ return is_mangled_component(s);
+}
+
+
+/*
+ see if a filename is an allowable 8.3 name.
+
+ we are only going to allow ascii characters in 8.3 names, as this
+ simplifies things greatly (it means that we know the string won't
+ get larger when converted from UNIX to DOS formats)
+*/
+static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards)
+{
+ int len, i;
+ char *dot_p;
+
+ /* as a special case, the names '.' and '..' are allowable 8.3 names */
+ if (name[0] == '.') {
+ if (!name[1] || (name[1] == '.' && !name[2])) {
+ return True;
+ }
+ }
+
+ /* the simplest test is on the overall length of the
+ filename. Note that we deliberately use the ascii string
+ length (not the multi-byte one) as it is faster, and gives us
+ the result we need in this case. Using strlen_m would not
+ only be slower, it would be incorrect */
+ len = strlen(name);
+ if (len > 12) return False;
+
+ /* find the '.'. Note that once again we use the non-multibyte
+ function */
+ dot_p = strchr(name, '.');
+
+ if (!dot_p) {
+ /* if the name doesn't contain a '.' then its length
+ must be less than 8 */
+ if (len > 8) {
+ return False;
+ }
+ } else {
+ int prefix_len, suffix_len;
+
+ /* if it does contain a dot then the prefix must be <=
+ 8 and the suffix <= 3 in length */
+ prefix_len = PTR_DIFF(dot_p, name);
+ suffix_len = len - (prefix_len+1);
+
+ if (prefix_len > 8 || suffix_len > 3) {
+ return False;
+ }
+
+ /* a 8.3 name cannot contain more than 1 '.' */
+ if (strchr(dot_p+1, '.')) {
+ return False;
+ }
+ }
+
+ /* the length are all OK. Now check to see if the characters themselves are OK */
+ for (i=0; name[i]; i++) {
+ /* note that we may allow wildcard petterns! */
+ if (!FLAG_CHECK(name[i], FLAG_ASCII|(allow_wildcards ? FLAG_WILDCARD : 0)) && name[i] != '.') {
+ return False;
+ }
+ }
+
+ /* it is a good 8.3 name */
+ return True;
+}
+
+
+/*
+ reset the mangling cache on a smb.conf reload. This only really makes sense for
+ mangling backends that have parameters in smb.conf, and as this backend doesn't
+ this is a NULL operation
+*/
+static void mangle_reset(void)
+{
+ /* noop */
+}
+
+
+/*
+ try to find a 8.3 name in the cache, and if found then
+ replace the string with the original long name.
+
+ The filename must be able to hold at least sizeof(fstring)
+*/
+static BOOL check_cache(char *name, size_t maxlen)
+{
+ u32 hash, multiplier;
+ int i;
+ const char *prefix;
+ char extension[4];
+
+ /* make sure that this is a mangled name from this cache */
+ if (!is_mangled(name)) {
+ DEBUG(10,("check_cache: %s -> not mangled\n", name));
+ return False;
+ }
+
+ /* we need to extract the hash from the 8.3 name */
+ hash = base_reverse[(unsigned char)name[7]];
+ for (multiplier=36, i=5;i>=1;i--) {
+ u32 v = base_reverse[(unsigned char)name[i]];
+ hash += multiplier * v;
+ multiplier *= 36;
+ }
+
+ /* now look in the prefix cache for that hash */
+ prefix = cache_lookup(hash);
+ if (!prefix) {
+ DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash));
+ return False;
+ }
+
+ /* we found it - construct the full name */
+ if (name[8] == '.') {
+ strncpy(extension, name+9, 3);
+ extension[3] = 0;
+ } else {
+ extension[0] = 0;
+ }
+
+ if (extension[0]) {
+ DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension));
+ slprintf(name, maxlen, "%s.%s", prefix, extension);
+ } else {
+ DEBUG(10,("check_cache: %s -> %s\n", name, prefix));
+ safe_strcpy(name, prefix, maxlen);
+ }
+
+ return True;
+}
+
+
+/*
+ look for a DOS reserved name
+*/
+static BOOL is_reserved_name(const char *name)
+{
+ if (FLAG_CHECK(name[0], FLAG_POSSIBLE1) &&
+ FLAG_CHECK(name[1], FLAG_POSSIBLE2) &&
+ FLAG_CHECK(name[2], FLAG_POSSIBLE3) &&
+ FLAG_CHECK(name[3], FLAG_POSSIBLE4)) {
+ /* a likely match, scan the lot */
+ int i;
+ for (i=0; reserved_names[i]; i++) {
+ int len = strlen(reserved_names[i]);
+ /* note that we match on COM1 as well as COM1.foo */
+ if (strncasecmp(name, reserved_names[i], len) == 0 &&
+ (name[len] == '.' || name[len] == 0)) {
+ return True;
+ }
+ }
+ }
+
+ return False;
+}
+
+/*
+ See if a filename is a legal long filename.
+ A filename ending in a '.' is not legal unless it's "." or "..". JRA.
+*/
+
+static BOOL is_legal_name(const char *name)
+{
+ const char *dot_pos = NULL;
+ BOOL alldots = True;
+ size_t numdots = 0;
+
+ while (*name) {
+ if (FLAG_CHECK(name[0], FLAG_ILLEGAL)) {
+ return False;
+ }
+ if (name[0] == '.') {
+ dot_pos = name;
+ numdots++;
+ } else {
+ alldots = False;
+ }
+ name++;
+ }
+
+ if (dot_pos) {
+ if (alldots && (numdots == 1 || numdots == 2))
+ return True; /* . or .. is a valid name */
+
+ /* A valid long name cannot end in '.' */
+ if (dot_pos[1] == '\0')
+ return False;
+ }
+
+ return True;
+}
+
+/*
+ the main forward mapping function, which converts a long filename to
+ a 8.3 name
+
+ if need83 is not set then we only do the mangling if the name is illegal
+ as a long name
+
+ if cache83 is not set then we don't cache the result
+
+ the name parameter must be able to hold 13 bytes
+*/
+static void name_map(char *name, BOOL need83, BOOL cache83)
+{
+ char *dot_p;
+ char lead_char;
+ char extension[4];
+ int extension_length, i;
+ int prefix_len;
+ u32 hash, v;
+ char new_name[13];
+
+ /* reserved names are handled specially */
+ if (!is_reserved_name(name)) {
+ /* if the name is already a valid 8.3 name then we don't need to
+ do anything */
+ if (is_8_3(name, False, False)) {
+ return;
+ }
+
+ /* if the caller doesn't strictly need 8.3 then just check for illegal
+ filenames */
+ if (!need83 && is_legal_name(name)) {
+ return;
+ }
+ }
+
+ /* find the '.' if any */
+ dot_p = strrchr(name, '.');
+
+ if (dot_p) {
+ /* if the extension contains any illegal characters or
+ is too long or zero length then we treat it as part
+ of the prefix */
+ for (i=0; i<4 && dot_p[i+1]; i++) {
+ if (! FLAG_CHECK(dot_p[i+1], FLAG_ASCII)) {
+ dot_p = NULL;
+ break;
+ }
+ }
+ if (i == 0 || i == 4) dot_p = NULL;
+ }
+
+ /* the leading character in the mangled name is taken from
+ the first character of the name, if it is ascii
+ otherwise '_' is used
+ */
+ lead_char = name[0];
+ if (! FLAG_CHECK(lead_char, FLAG_ASCII)) {
+ lead_char = '_';
+ }
+ lead_char = toupper(lead_char);
+
+ /* the prefix is anything up to the first dot */
+ if (dot_p) {
+ prefix_len = PTR_DIFF(dot_p, name);
+ } else {
+ prefix_len = strlen(name);
+ }
+
+ /* the extension of the mangled name is taken from the first 3
+ ascii chars after the dot */
+ extension_length = 0;
+ if (dot_p) {
+ for (i=1; extension_length < 3 && dot_p[i]; i++) {
+ char c = dot_p[i];
+ if (FLAG_CHECK(c, FLAG_ASCII)) {
+ extension[extension_length++] = toupper(c);
+ }
+ }
+ }
+
+ /* find the hash for this prefix */
+ v = hash = mangle_hash(name, prefix_len);
+
+ /* now form the mangled name. */
+ new_name[0] = lead_char;
+ new_name[7] = base_forward(v % 36);
+ new_name[6] = '~';
+ for (i=5; i>=1; i--) {
+ v = v / 36;
+ new_name[i] = base_forward(v % 36);
+ }
+
+ /* add the extension */
+ if (extension_length) {
+ new_name[8] = '.';
+ memcpy(&new_name[9], extension, extension_length);
+ new_name[9+extension_length] = 0;
+ } else {
+ new_name[8] = 0;
+ }
+
+ if (cache83) {
+ /* put it in the cache */
+ cache_insert(name, prefix_len, hash);
+ }
+
+ DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n",
+ name, hash, new_name, cache83));
+
+ /* and overwrite the old name */
+ fstrcpy(name, new_name);
+
+ /* all done, we've managed to mangle it */
+}
+
+
+/* initialise the flags table
+
+ we allow only a very restricted set of characters as 'ascii' in this
+ mangling backend. This isn't a significant problem as modern clients
+ use the 'long' filenames anyway, and those don't have these
+ restrictions.
+*/
+static void init_tables(void)
+{
+ int i;
+
+ memset(char_flags, 0, sizeof(char_flags));
+
+ for (i=0;i<128;i++) {
+ if ((i >= '0' && i <= '9') ||
+ (i >= 'a' && i <= 'z') ||
+ (i >= 'A' && i <= 'Z')) {
+ char_flags[i] |= (FLAG_ASCII | FLAG_BASECHAR);
+ }
+ if (strchr("_-$~", i)) {
+ char_flags[i] |= FLAG_ASCII;
+ }
+
+ if (strchr("*\\/?<>|\":", i)) {
+ char_flags[i] |= FLAG_ILLEGAL;
+ }
+
+ if (strchr("*?\"<>", i)) {
+ char_flags[i] |= FLAG_WILDCARD;
+ }
+ }
+
+ memset(base_reverse, 0, sizeof(base_reverse));
+ for (i=0;i<36;i++) {
+ base_reverse[(unsigned char)base_forward(i)] = i;
+ }
+
+ /* fill in the reserved names flags. These are used as a very
+ fast filter for finding possible DOS reserved filenames */
+ for (i=0; reserved_names[i]; i++) {
+ unsigned char c1, c2, c3, c4;
+
+ c1 = (unsigned char)reserved_names[i][0];
+ c2 = (unsigned char)reserved_names[i][1];
+ c3 = (unsigned char)reserved_names[i][2];
+ c4 = (unsigned char)reserved_names[i][3];
+
+ char_flags[c1] |= FLAG_POSSIBLE1;
+ char_flags[c2] |= FLAG_POSSIBLE2;
+ char_flags[c3] |= FLAG_POSSIBLE3;
+ char_flags[c4] |= FLAG_POSSIBLE4;
+ char_flags[tolower(c1)] |= FLAG_POSSIBLE1;
+ char_flags[tolower(c2)] |= FLAG_POSSIBLE2;
+ char_flags[tolower(c3)] |= FLAG_POSSIBLE3;
+ char_flags[tolower(c4)] |= FLAG_POSSIBLE4;
+
+ char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4;
+ }
+}
+
+
+/*
+ the following provides the abstraction layer to make it easier
+ to drop in an alternative mangling implementation */
+static struct mangle_fns mangle_fns = {
+ is_mangled,
+ is_8_3,
+ mangle_reset,
+ check_cache,
+ name_map
+};
+
+/* return the methods for this mangling implementation */
+struct mangle_fns *mangle_hash2_init(void)
+{
+ init_tables();
+ mangle_reset();
+
+ if (!cache_init()) {
+ return NULL;
+ }
+
+ return &mangle_fns;
+}
diff --git a/jerry2/source/smbd/reply.c b/jerry2/source/smbd/reply.c
new file mode 100644
index 00000000000..0efc29cb768
--- /dev/null
+++ b/jerry2/source/smbd/reply.c
@@ -0,0 +1,5173 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB reply routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+ This file handles most of the reply_ calls that the server
+ makes to handle specific protocols
+*/
+
+
+#include "includes.h"
+
+/* look in server.c for some explanation of these variables */
+extern int Protocol;
+extern int max_send;
+extern int max_recv;
+extern char magic_char;
+extern BOOL case_sensitive;
+extern BOOL case_preserve;
+extern BOOL short_case_preserve;
+extern userdom_struct current_user_info;
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+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() );
+ }
+}
+
+
+/****************************************************************************
+ Reply to an special message.
+****************************************************************************/
+
+int reply_special(char *inbuf,char *outbuf)
+{
+ int outsize = 4;
+ int msg_type = CVAL(inbuf,0);
+ int msg_flags = CVAL(inbuf,1);
+ pstring name1,name2;
+ extern fstring remote_machine;
+ extern fstring local_machine;
+ int len;
+ char name_type = 0;
+
+ *name1 = *name2 = 0;
+
+ memset(outbuf,'\0',smb_size);
+
+ smb_setlen(outbuf,0);
+
+ switch (msg_type) {
+ case 0x81: /* session request */
+ SCVAL(outbuf,0,0x82);
+ SCVAL(outbuf,3,0);
+ if (name_len(inbuf+4) > 50 ||
+ name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
+ DEBUG(0,("Invalid name length in session request\n"));
+ return(0);
+ }
+ name_extract(inbuf,4,name1);
+ name_extract(inbuf,4 + name_len(inbuf + 4),name2);
+ DEBUG(2,("netbios connect: name1=%s name2=%s\n",
+ name1,name2));
+
+ fstrcpy(remote_machine,name2);
+ remote_machine[15] = 0;
+ trim_string(remote_machine," "," ");
+ strlower(remote_machine);
+ alpha_strcpy(remote_machine,remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
+
+ fstrcpy(local_machine,name1);
+ len = strlen(local_machine);
+ if (len == 16) {
+ name_type = local_machine[15];
+ local_machine[15] = 0;
+ }
+ trim_string(local_machine," "," ");
+ strlower(local_machine);
+ alpha_strcpy(local_machine,local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
+
+ DEBUG(2,("netbios connect: local=%s remote=%s\n",
+ local_machine, remote_machine ));
+
+ if (name_type == 'R') {
+ /* We are being asked for a pathworks session ---
+ no thanks! */
+ SCVAL(outbuf, 0, 0x83);
+ break;
+ }
+
+ /* add it as a possible user name if we
+ are in share mode security */
+ if (lp_security() == SEC_SHARE) {
+ add_session_user(remote_machine);
+ }
+
+ reload_services(True);
+ reopen_logs();
+
+ if (lp_status(-1))
+ claim_connection(NULL,"",0,True);
+
+ break;
+
+ case 0x89: /* session keepalive request
+ (some old clients produce this?) */
+ SCVAL(outbuf,0,0x85);
+ SCVAL(outbuf,3,0);
+ break;
+
+ case 0x82: /* positive session response */
+ case 0x83: /* negative session response */
+ case 0x84: /* retarget session response */
+ DEBUG(0,("Unexpected session response\n"));
+ break;
+
+ case 0x85: /* session keepalive */
+ default:
+ return(0);
+ }
+
+ DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
+ msg_type, msg_flags));
+
+ return(outsize);
+}
+
+/*******************************************************************
+ Work out what error to give to a failed connection.
+********************************************************************/
+
+static int connection_error(char *outbuf, int ecode)
+{
+ if (ecode == ERRnoipc || ecode == ERRnosuchshare)
+ return(ERROR_DOS(ERRDOS,ecode));
+
+ return(ERROR_DOS(ERRSRV,ecode));
+}
+
+/****************************************************************************
+ Parse a share descriptor string.
+****************************************************************************/
+
+static void parse_connect(char *p,char *service,char *user,
+ char *password,int *pwlen,char *dev)
+{
+ char *p2;
+
+ DEBUG(4,("parsing connect string %s\n",p));
+
+ p2 = strrchr(p,'\\');
+ if (p2 == NULL)
+ fstrcpy(service,p);
+ else
+ fstrcpy(service,p2+1);
+
+ p += strlen(p) + 2;
+
+ fstrcpy(password,p);
+ *pwlen = strlen(password);
+
+ p += strlen(p) + 2;
+
+ fstrcpy(dev,p);
+
+ *user = 0;
+ p = strchr(service,'%');
+ if (p != NULL)
+ {
+ *p = 0;
+ fstrcpy(user,p+1);
+ }
+}
+
+/****************************************************************************
+ 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;
+ pstring dev;
+ int outsize = 0;
+ uint16 vuid = SVAL(inbuf,smb_uid);
+ int pwlen=0;
+ int ecode = -1;
+ START_PROFILE(SMBtcon);
+
+ *service = *user = *password = *dev = 0;
+
+ parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev);
+
+ /*
+ * If the vuid is valid, we should be using that....
+ */
+
+ if (*user == '\0' && (lp_security() != SEC_SHARE) && validated_username(vuid)) {
+ pstrcpy(user,validated_username(vuid));
+ }
+
+ /*
+ * Ensure the user and password names are in UNIX codepage format.
+ */
+
+ pstrcpy(user,dos_to_unix_static(user));
+ if (!doencrypt)
+ pstrcpy(password,dos_to_unix_static(password));
+
+ /*
+ * 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);
+
+ if (!conn) {
+ END_PROFILE(SMBtcon);
+ return(connection_error(outbuf,ecode));
+ }
+
+ outsize = set_message(outbuf,2,0,True);
+ SSVAL(outbuf,smb_vwv0,max_recv);
+ SSVAL(outbuf,smb_vwv1,conn->cnum);
+ SSVAL(outbuf,smb_tid,conn->cnum);
+
+ DEBUG(3,("tcon service=%s user=%s cnum=%d\n",
+ service, user, conn->cnum));
+
+ END_PROFILE(SMBtcon);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a tcon and X.
+****************************************************************************/
+
+int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+{
+ fstring 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);
+ char *path;
+ char *p;
+ START_PROFILE(SMBtconX);
+
+ *service = *user = *password = *devicename = 0;
+
+ /* we might have to close an old one */
+ if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
+ close_cnum(conn,vuid);
+ }
+
+ if (passlen > MAX_PASS_LEN) {
+ overflow_attack(passlen);
+ return(ERROR_DOS(ERRDOS,ERRbuftoosmall));
+ }
+
+ memcpy(password,smb_buf(inbuf),passlen);
+ password[passlen]=0;
+ path = smb_buf(inbuf) + passlen;
+
+ if (passlen != 24) {
+ if (strequal(password," "))
+ *password = 0;
+ passlen = strlen(password);
+ }
+
+ /*
+ * the service name can be either: \\server\share
+ * or share directly like on the DELL PowerVault 705
+ */
+ if (*path=='\\') {
+ p = strchr(path+2,'\\');
+ if (!p) {
+ END_PROFILE(SMBtconX);
+ return(ERROR_DOS(ERRDOS,ERRnosuchshare));
+ }
+ fstrcpy(service,p+1);
+ }
+ else
+ fstrcpy(service,path);
+
+ p = strchr(service,'%');
+ if (p) {
+ *p++ = 0;
+ fstrcpy(user,p);
+ }
+ StrnCpy(devicename,path + strlen(path) + 1,6);
+ DEBUG(4,("Got device type %s\n",devicename));
+
+ /*
+ * If the vuid is valid, we should be using that....
+ */
+
+ if (*user == '\0' && (lp_security() != SEC_SHARE) && validated_username(vuid)) {
+ pstrcpy(user,validated_username(vuid));
+ }
+
+ /*
+ * Ensure the user and password names are in UNIX codepage format.
+ */
+
+ pstrcpy(user,dos_to_unix_static(user));
+ if (!doencrypt)
+ pstrcpy(password,dos_to_unix_static(password));
+
+ /*
+ * 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) {
+ END_PROFILE(SMBtconX);
+ return(connection_error(outbuf,ecode));
+ }
+
+ if (Protocol < PROTOCOL_NT1) {
+ set_message(outbuf,2,strlen(devicename)+1,True);
+ pstrcpy(smb_buf(outbuf),devicename);
+ } else {
+ char *fsname = lp_fstype(SNUM(conn));
+
+ set_message(outbuf,3,3,True);
+
+ p = smb_buf(outbuf);
+ pstrcpy(p,devicename); p = skip_string(p,1); /* device name */
+ pstrcpy(p,fsname); p = skip_string(p,1); /* filesystem type e.g NTFS */
+
+ set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
+
+ /* what does setting this bit do? It is set by NT4 and
+ may affect the ability to autorun mounted cdroms */
+ SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
+ (lp_csc_policy(SNUM(conn)) << 2));
+
+ init_dfsroot(conn, inbuf, outbuf);
+ }
+
+
+ DEBUG(3,("tconX service=%s user=%s\n",
+ service, user));
+
+ /* set the incoming and outgoing tid to the just created one */
+ SSVAL(inbuf,smb_tid,conn->cnum);
+ SSVAL(outbuf,smb_tid,conn->cnum);
+
+ END_PROFILE(SMBtconX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
+}
+
+/****************************************************************************
+ Reply to an unknown type.
+****************************************************************************/
+
+int reply_unknown(char *inbuf,char *outbuf)
+{
+ int type;
+ type = CVAL(inbuf,smb_com);
+
+ DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
+ smb_fn_name(type), type, type));
+
+ return(ERROR_DOS(ERRSRV,ERRunknownsmb));
+}
+
+/****************************************************************************
+ Reply to an ioctl.
+****************************************************************************/
+
+int reply_ioctl(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ uint16 device = SVAL(inbuf,smb_vwv1);
+ uint16 function = SVAL(inbuf,smb_vwv2);
+ uint32 ioctl_code = (device << 16) + function;
+ int replysize, outsize;
+ char *p;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBioctl);
+
+ DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
+
+ switch (ioctl_code)
+ {
+ case IOCTL_QUERY_JOB_INFO:
+ replysize = 32;
+ break;
+ default:
+ END_PROFILE(SMBioctl);
+ return(ERROR_DOS(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,fsp->print_jobid); /* Job number */
+ StrnCpy(p+2, global_myname, 15); /* Our NetBIOS name */
+ StrnCpy(p+18, lp_servicename(SNUM(conn)), 13); /* Service name */
+ break;
+ }
+
+ END_PROFILE(SMBioctl);
+ return outsize;
+}
+
+/****************************************************************************
+ Always return an error: it's just a matter of which one...
+ ****************************************************************************/
+
+static int session_trust_account(connection_struct *conn, char *inbuf, char *outbuf, char *user,
+ char *smb_passwd, int smb_passlen,
+ char *smb_nt_passwd, int smb_nt_passlen)
+{
+ SAM_ACCOUNT *sam_trust_acct = NULL; /* check if trust account exists */
+ uint16 acct_ctrl;
+
+ if (lp_security() == SEC_USER) {
+ pdb_init_sam(&sam_trust_acct);
+ pdb_getsampwnam(sam_trust_acct, user);
+ } else {
+ DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
+ }
+
+ if (sam_trust_acct == NULL) {
+ /* lkclXXXX: workstation entry doesn't exist */
+ DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user));
+ return(ERROR_BOTH(NT_STATUS_NO_SUCH_USER,ERRDOS,1317));
+ } else {
+ if ((smb_passlen != 24) || (smb_nt_passlen != 24)) {
+ DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
+ }
+
+ if (!smb_password_ok(sam_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd)) {
+ DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
+ }
+
+ acct_ctrl = pdb_get_acct_ctrl(sam_trust_acct);
+ if (acct_ctrl & ACB_DOMTRUST) {
+ DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT,ERRDOS,1807));
+ }
+
+ if (acct_ctrl & ACB_SVRTRUST) {
+ DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT,ERRDOS,1809));
+ }
+
+ if (acct_ctrl & ACB_WSTRUST) {
+ DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT,ERRDOS,1808));
+ }
+ }
+
+ /* don't know what to do: indicate logon failure */
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRDOS,1326));
+}
+
+/****************************************************************************
+ Create a UNIX user on demand.
+****************************************************************************/
+
+int smb_create_user(char *unix_user, char *homedir)
+{
+ pstring add_script;
+ int ret;
+
+ pstrcpy(add_script, lp_adduser_script());
+ if (! *add_script)
+ return -1;
+ all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
+ if (homedir)
+ all_string_sub(add_script, "%H", homedir, sizeof(pstring));
+ ret = smbrun(add_script,NULL);
+ 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;
+
+ /*
+ * Sanity check -- do not delete 'root' account
+ */
+
+ if (StrCaseCmp("root", unix_user) == 0) {
+ DEBUG(0,("smb_delete_user: Will not delete the [%s] user account!\n", unix_user));
+ return -1;
+ }
+
+ pstrcpy(del_script, lp_deluser_script());
+ if (! *del_script)
+ return -1;
+ all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
+ ret = smbrun(del_script,NULL);
+ 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, 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;
+
+ 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() && !smb_getpwnam(unix_user,True))
+ smb_create_user(unix_user, NULL);
+ }
+
+ 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, NT_USER_TOKEN **pptoken)
+{
+ BOOL ret = False;
+ BOOL user_exists = True;
+ struct passwd *pwd = NULL;
+
+ 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, pptoken);
+
+ 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() && !(pwd = smb_getpwnam(unix_user,True))) {
+ smb_create_user(unix_user, NULL);
+ }
+
+ if(lp_adduser_script() && pwd) {
+ SMB_STRUCT_STAT st;
+
+ /*
+ * Also call smb_create_user if the users home directory
+ * doesn't exist. Used with winbindd to allow the script to
+ * create the home directory for a user mapped with winbindd.
+ */
+
+ if (pwd->pw_dir && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT))
+ smb_create_user(unix_user, pwd->pw_dir);
+ }
+
+ } 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() && smb_getpwnam(unix_user,True)) {
+ smb_delete_user(unix_user);
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ Reply to a session setup command.
+****************************************************************************/
+
+int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+{
+ int sess_vuid;
+ gid_t gid;
+ uid_t uid;
+ int smb_bufsize;
+ int smb_apasslen = 0;
+ pstring smb_apasswd;
+ int smb_ntpasslen = 0;
+ pstring smb_ntpasswd;
+ BOOL valid_nt_password = False;
+ BOOL valid_lm_password = False;
+ fstring user;
+ fstring orig_user;
+ BOOL guest=False;
+ static BOOL done_sesssetup = False;
+ BOOL doencrypt = SMBENCRYPT();
+ fstring domain;
+ NT_USER_TOKEN *ptok = NULL;
+
+ START_PROFILE(SMBsesssetupX);
+
+ *smb_apasswd = 0;
+ *smb_ntpasswd = 0;
+ *domain = 0;
+
+ smb_bufsize = SVAL(inbuf,smb_vwv2);
+
+ if (Protocol < PROTOCOL_NT1) {
+ smb_apasslen = SVAL(inbuf,smb_vwv7);
+ if (smb_apasslen > MAX_PASS_LEN) {
+ overflow_attack(smb_apasslen);
+ return(ERROR_DOS(ERRDOS,ERRbuftoosmall));
+ }
+
+ memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
+ smb_apasswd[smb_apasslen] = 0;
+ fstrcpy(user,smb_buf(inbuf)+smb_apasslen);
+ /*
+ * Incoming user is in DOS codepage format. Convert
+ * to UNIX.
+ */
+ fstrcpy(user,dos_to_unix_static(user));
+
+ if (!doencrypt && (lp_security() != SEC_SERVER)) {
+ smb_apasslen = strlen(smb_apasswd);
+ }
+ } 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);
+ char *username_str;
+ fstring native_lanman;
+
+
+ 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_WIN2K || ra_type == RA_WIN95) {
+ if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
+ set_remote_arch( RA_WIN95);
+ }
+ }
+
+ username_str = smb_buf(inbuf)+smb_apasslen;
+ fstrcpy( native_lanman, skip_string(username_str, 3));
+
+ /*
+ * we distinguish between 2K and XP by the "Native Lan Manager"
+ * string.
+ * .NET RC2 => "Windows .NET 5.2"
+ * WinXP => "Windows 2002 5.1"
+ * Win2k => "Windows 2000 5.0"
+ * NT4 => (off by one bug) "Windows NT 4.0"
+ * Win9x => "Windows 4.0"
+ */
+ if ( ra_type == RA_WIN2K ) {
+ if ( 0 == strcmp( native_lanman, "Windows 2002 5.1" ) )
+ set_remote_arch( RA_WINXP );
+ else if ( 0 == strcmp( native_lanman, "Windows .NET 5.2" ) )
+ set_remote_arch( RA_WIN2K3 );
+ }
+
+ if (passlen1 != 24 && passlen2 != 24)
+ doencrypt = False;
+
+ if (passlen1 > MAX_PASS_LEN) {
+ overflow_attack(passlen1);
+ return(ERROR_DOS(ERRDOS,ERRbuftoosmall));
+ }
+
+ passlen1 = MIN(passlen1, MAX_PASS_LEN);
+ passlen2 = MIN(passlen2, MAX_PASS_LEN);
+
+ if(!doencrypt) {
+ /* both Win95 and WinNT stuff up the password lengths for
+ non-encrypting systems. Uggh.
+
+ if passlen1==24 its a win95 system, and its setting the
+ password length incorrectly. Luckily it still works with the
+ default code because Win95 will null terminate the password
+ anyway
+
+ 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. */
+
+ if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
+ passlen2 = 0;
+ }
+
+ 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);
+ smb_apasswd[smb_apasslen] = 0;
+ 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) {
+ pstrcpy(smb_apasswd,dos_to_unix_static(smb_apasswd));
+ pstrcpy(smb_ntpasswd,dos_to_unix_static(smb_ntpasswd));
+ }
+
+ } 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.
+ */
+ pstrcpy(smb_apasswd,dos_to_unix_static(smb_apasswd));
+
+ /* 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;
+ }
+ }
+
+ p += passlen1 + passlen2;
+ fstrcpy(user,p);
+ p = skip_string(p,1);
+ /*
+ * Incoming user and domain are in DOS codepage format. Convert
+ * to UNIX.
+ */
+ fstrcpy(user,dos_to_unix_static(user));
+ fstrcpy(domain, dos_to_unix_static(p));
+ DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
+ domain,skip_string(p,1),skip_string(p,2)));
+ }
+
+ /* don't allow strange characters in usernames or domains */
+ alpha_strcpy(user, user, ". _-$", sizeof(user));
+ alpha_strcpy(domain, domain, ". _-@", sizeof(domain));
+ if (strstr(user, "..") || strstr(domain,"..")) {
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
+ }
+
+ 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 && (user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) {
+ END_PROFILE(SMBsesssetupX);
+ 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"));
+ END_PROFILE(SMBsesssetupX);
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ }
+ }
+
+ /* setup %U substitution */
+ sub_set_smb_name(user);
+
+ /* If no username is sent use the guest account */
+ if (!*user) {
+ fstrcpy(user,lp_guestaccount(-1));
+ guest = True;
+ }
+
+ fstrcpy(current_user_info.smb_name,user);
+
+ reload_services(True);
+
+ /*
+ * Save the username before mapping. We will use
+ * the original username sent to us for security=server
+ * and security=domain checking.
+ */
+
+ fstrcpy( orig_user, user);
+
+ /*
+ * Always try the "DOMAIN\user" lookup first, as this is the most
+ * specific case. If this fails then try the simple "user" lookup.
+ */
+
+ {
+ fstring dom_user;
+
+ /* Work out who's who */
+
+ slprintf(dom_user, sizeof(dom_user) - 1,"%s%s%s",
+ domain, lp_winbind_separator(), user);
+
+ if (sys_getpwnam(dom_user) != NULL) {
+ fstrcpy(user, dom_user);
+ DEBUG(3,("Using unix username %s\n", dom_user));
+ }
+ }
+
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ (void)map_username(user);
+
+ /*
+ * Do any UNIX username case mangling.
+ */
+ smb_getpwnam(user, True);
+
+ add_session_user(user);
+
+ /*
+ * Check with orig_user for security=server and
+ * security=domain.
+ */
+
+ if (!guest && !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, &ptok) &&
+ !check_hosts_equiv(user))
+ {
+
+ /*
+ * If we get here then the user wasn't guest and the remote
+ * authentication methods failed. Check the authentication
+ * methods on this local server.
+ *
+ * If an NT password was supplied try and validate with that
+ * first. This is superior as the passwords are mixed case
+ * 128 length unicode.
+ */
+
+ if(smb_ntpasslen)
+ {
+ if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL))
+ DEBUG(2,("NT Password did not match for user '%s'!\n", user));
+ else
+ valid_nt_password = True;
+ }
+
+
+ /* check the LanMan password only if necessary and if allowed
+ by lp_lanman_auth() */
+ if (!valid_nt_password && lp_lanman_auth())
+ {
+ DEBUG(2,("Defaulting to Lanman password for %s\n", user));
+ valid_lm_password = password_ok(user, smb_apasswd,smb_apasslen,NULL);
+ }
+
+
+ /* The true branch will be executed if
+ (1) the NT password failed (or was not tried), and
+ (2) LanMan authentication failed (or was disabled)
+ */
+ if (!valid_nt_password && !valid_lm_password)
+ {
+ if (lp_security() >= SEC_USER)
+ {
+ if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
+ {
+ delete_nt_token(&ptok);
+ DEBUG(1,("Rejecting user '%s': authentication failed\n", user));
+ END_PROFILE(SMBsesssetupX);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
+ }
+
+ if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
+ {
+ SAM_ACCOUNT *sampass = NULL;
+
+ pdb_init_sam(&sampass);
+
+ /*
+ * This is really bad form. We know that password_ok() failed,
+ * but the return value can't distinguish between a non-existent user
+ * and a bad password. So we try to look the user up again here
+ * to see if he or she exists. We must look up the user in the
+ * "smb passwd file" and not /etc/passwd so that we don't
+ * get confused when the two don't have a one-to-one correspondence.
+ * e.g. a standard UNIX account such as "operator" --jerry
+ */
+
+ if (pdb_getsampwnam(sampass, user))
+ {
+ delete_nt_token(&ptok);
+ DEBUG(1,("Rejecting user '%s': bad password\n", user));
+ END_PROFILE(SMBsesssetupX);
+ pdb_free_sam(sampass);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
+ }
+
+ pdb_free_sam(sampass);
+ }
+
+ /*
+ * ..else if lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
+ * Then always map to guest account - as done below.
+ */
+ }
+
+ if (*smb_apasswd || !smb_getpwnam(user,True))
+ fstrcpy(user,lp_guestaccount(-1));
+ DEBUG(3,("Registered username %s for guest access\n",user));
+ guest = True;
+ }
+ }
+
+ if (!smb_getpwnam(user,True)) {
+ DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
+ fstrcpy(user,lp_guestaccount(-1));
+ guest = True;
+ }
+
+ if (!strequal(user,lp_guestaccount(-1)) &&
+ lp_servicenumber(user) < 0)
+ {
+ add_home_service(user,get_user_service_home_dir(user));
+ }
+
+
+ /* it's ok - setup a reply */
+ if (Protocol < PROTOCOL_NT1) {
+ set_message(outbuf,3,0,True);
+ } else {
+ char *p;
+ set_message(outbuf,3,3,True);
+ p = smb_buf(outbuf);
+ pstrcpy(p,"Unix"); p = skip_string(p,1);
+ pstrcpy(p,"Samba "); pstrcat(p,VERSION); p = skip_string(p,1);
+ pstrcpy(p,global_myworkgroup); unix_to_dos(p); p = skip_string(p,1);
+ set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
+ /* perhaps grab OS version here?? */
+ }
+
+ /* Set the correct uid in the outgoing and incoming packets
+ We will use this on future requests to determine which
+ user we should become.
+ */
+ {
+ const struct passwd *pw = smb_getpwnam(user,False);
+ if (!pw) {
+ delete_nt_token(&ptok);
+ DEBUG(1,("Username %s is invalid on this system\n",user));
+ END_PROFILE(SMBsesssetupX);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
+ }
+ gid = pw->pw_gid;
+ uid = pw->pw_uid;
+ }
+
+ if (guest)
+ SSVAL(outbuf,smb_vwv2,1);
+
+ /* 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,current_user_info.smb_name,domain,guest,&ptok);
+
+ delete_nt_token(&ptok);
+
+ if (sess_vuid == -1) {
+ END_PROFILE(SMBsesssetupX);
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ }
+
+ SSVAL(outbuf,smb_uid,sess_vuid);
+ SSVAL(inbuf,smb_uid,sess_vuid);
+
+ if (!done_sesssetup)
+ max_send = MIN(max_send,smb_bufsize);
+
+ DEBUG(6,("Client requested max send size of %d\n", max_send));
+
+ done_sesssetup = True;
+
+ END_PROFILE(SMBsesssetupX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
+}
+
+/****************************************************************************
+ Reply to a chkpth.
+****************************************************************************/
+
+int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = 0;
+ int mode;
+ pstring name;
+ BOOL ok = False;
+ BOOL bad_path = False;
+ SMB_STRUCT_STAT sbuf;
+ START_PROFILE(SMBchkpth);
+
+ pstrcpy(name,smb_buf(inbuf) + 1);
+
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+
+ unix_convert(name,conn,0,&bad_path,&sbuf);
+
+ mode = SVAL(inbuf,smb_vwv0);
+
+ if (check_name(name,conn)) {
+ if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0)
+ ok = S_ISDIR(sbuf.st_mode);
+ }
+
+ if (!ok) {
+ /* We special case this - as when a Windows machine
+ is parsing a path is steps through the components
+ one at a time - if a component fails it expects
+ ERRbadpath, not ERRbadfile.
+ */
+ if(errno == ENOENT) {
+ return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+ }
+
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+
+ outsize = set_message(outbuf,0,0,True);
+
+ DEBUG(3,("chkpth %s mode=%d\n", name, mode));
+
+ END_PROFILE(SMBchkpth);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a getatr.
+****************************************************************************/
+
+int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ pstring fname;
+ int outsize = 0;
+ SMB_STRUCT_STAT sbuf;
+ BOOL ok = False;
+ int mode=0;
+ SMB_OFF_T size=0;
+ time_t mtime=0;
+ BOOL bad_path = False;
+ START_PROFILE(SMBgetatr);
+
+ pstrcpy(fname,smb_buf(inbuf) + 1);
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
+ under WfWg - weird! */
+ if (! (*fname))
+ {
+ mode = aHIDDEN | aDIR;
+ if (!CAN_WRITE(conn)) mode |= aRONLY;
+ size = 0;
+ mtime = 0;
+ ok = True;
+ }
+ else
+ {
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (check_name(fname,conn))
+ {
+ if (VALID_STAT(sbuf) || vfs_stat(conn,fname,&sbuf) == 0)
+ {
+ mode = dos_mode(conn,fname,&sbuf);
+ size = sbuf.st_size;
+ mtime = sbuf.st_mtime;
+ if (mode & aDIR)
+ size = 0;
+ ok = True;
+ }
+ else
+ DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
+ }
+ }
+
+ if (!ok)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBgetatr);
+ return(UNIXERROR(ERRDOS,ERRbadfile));
+ }
+
+ outsize = set_message(outbuf,10,0,True);
+
+ SSVAL(outbuf,smb_vwv0,mode);
+ if(lp_dos_filetime_resolution(SNUM(conn)) )
+ put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
+ else
+ put_dos_date3(outbuf,smb_vwv1,mtime);
+ SIVAL(outbuf,smb_vwv3,(uint32)size);
+
+ if (Protocol >= PROTOCOL_NT1)
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
+
+ DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
+
+ END_PROFILE(SMBgetatr);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a setatr.
+****************************************************************************/
+
+int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ pstring fname;
+ int outsize = 0;
+ BOOL ok=False;
+ int mode;
+ time_t mtime;
+ SMB_STRUCT_STAT sbuf;
+ BOOL bad_path = False;
+ START_PROFILE(SMBsetatr);
+
+ pstrcpy(fname,smb_buf(inbuf) + 1);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+
+ mode = SVAL(inbuf,smb_vwv0);
+ mtime = make_unix_date3(inbuf+smb_vwv1);
+
+ if (VALID_STAT_OF_DIR(sbuf))
+ mode |= aDIR;
+ else
+ mode &= ~aDIR;
+
+ if (check_name(fname,conn))
+ ok = (file_chmod(conn,fname,mode,NULL) == 0);
+ if (ok)
+ ok = set_filetime(conn,fname,mtime);
+
+ if (!ok)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBsetatr);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ outsize = set_message(outbuf,0,0,True);
+
+ DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
+
+ END_PROFILE(SMBsetatr);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a dskattr.
+****************************************************************************/
+
+int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = 0;
+ SMB_BIG_UINT dfree,dsize,bsize;
+ START_PROFILE(SMBdskattr);
+
+ conn->vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize);
+
+ outsize = set_message(outbuf,5,0,True);
+
+ if (Protocol <= PROTOCOL_LANMAN2) {
+ double total_space, free_space;
+ /* we need to scale this to a number that DOS6 can handle. We
+ use floating point so we can handle large drives on systems
+ that don't have 64 bit integers
+
+ we end up displaying a maximum of 2G to DOS systems
+ */
+ total_space = dsize * (double)bsize;
+ free_space = dfree * (double)bsize;
+
+ dsize = (total_space+63*512) / (64*512);
+ dfree = (free_space+63*512) / (64*512);
+
+ if (dsize > 0xFFFF) dsize = 0xFFFF;
+ if (dfree > 0xFFFF) dfree = 0xFFFF;
+
+ SSVAL(outbuf,smb_vwv0,dsize);
+ SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
+ SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
+ SSVAL(outbuf,smb_vwv3,dfree);
+ } else {
+ SSVAL(outbuf,smb_vwv0,dsize);
+ SSVAL(outbuf,smb_vwv1,bsize/512);
+ SSVAL(outbuf,smb_vwv2,512);
+ SSVAL(outbuf,smb_vwv3,dfree);
+ }
+
+ DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
+
+ END_PROFILE(SMBdskattr);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a search.
+ Can be called from SMBsearch, SMBffirst or SMBfunique.
+****************************************************************************/
+
+int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ pstring mask;
+ pstring directory;
+ pstring fname;
+ SMB_OFF_T size;
+ int mode;
+ time_t date;
+ int dirtype;
+ int outsize = 0;
+ int numentries = 0;
+ BOOL finished = False;
+ int maxentries;
+ int i;
+ char *p;
+ BOOL ok = False;
+ int status_len;
+ char *path;
+ char status[21];
+ int dptr_num= -1;
+ BOOL check_descend = False;
+ BOOL expect_close = False;
+ BOOL can_open = True;
+ BOOL bad_path = False;
+ START_PROFILE(SMBsearch);
+
+ *mask = *directory = *fname = 0;
+
+ /* If we were called as SMBffirst then we must expect close. */
+ if(CVAL(inbuf,smb_com) == SMBffirst)
+ expect_close = True;
+
+ outsize = set_message(outbuf,1,3,True);
+ maxentries = SVAL(inbuf,smb_vwv0);
+ dirtype = SVAL(inbuf,smb_vwv1);
+ path = smb_buf(inbuf) + 1;
+ status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
+
+ RESOLVE_DFSPATH(path, conn, inbuf, outbuf);
+ /* dirtype &= ~aDIR; */
+
+ if (status_len == 0)
+ {
+ SMB_STRUCT_STAT sbuf;
+ pstring dir2;
+
+ pstrcpy(directory,smb_buf(inbuf)+1);
+ pstrcpy(dir2,smb_buf(inbuf)+1);
+ unix_convert(directory,conn,0,&bad_path,&sbuf);
+ unix_format(dir2);
+
+ if (!check_name(directory,conn))
+ can_open = False;
+
+ p = strrchr(dir2,'/');
+ if (p == NULL)
+ {
+ pstrcpy(mask,dir2);
+ *dir2 = 0;
+ }
+ else
+ {
+ *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);
+ SCVAL(status,0,(dirtype & 0x1F));
+ }
+ else
+ {
+ int status_dirtype;
+ memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
+ status_dirtype = CVAL(status,0) & 0x1F;
+ if (status_dirtype != (dirtype & 0x1F))
+ dirtype = status_dirtype;
+ conn->dirptr = dptr_fetch(status+12,&dptr_num);
+ if (!conn->dirptr)
+ goto SearchEmpty;
+ string_set(&conn->dirpath,dptr_path(dptr_num));
+ fstrcpy(mask, dptr_wcard(dptr_num));
+ }
+
+ if (can_open)
+ {
+ p = smb_buf(outbuf) + 3;
+
+ 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)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBsearch);
+ return (UNIXERROR(ERRDOS,ERRnofids));
+ }
+ END_PROFILE(SMBsearch);
+ return ERROR_DOS(ERRDOS,ERRnofids);
+ }
+ dptr_set_wcard(dptr_num, strdup(mask));
+ dptr_set_attr(dptr_num, dirtype);
+ } else {
+ dirtype = dptr_attr(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++)
+ {
+ /* check to make sure we have room in the buffer */
+ if ( ((PTR_DIFF(p, outbuf))+DIR_STRUCT_SIZE) > BUFFER_SIZE )
+ break;
+ 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:
+
+ if ( (numentries == 0) || !ok)
+ {
+ SCVAL(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)
+ {
+ SCVAL(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);
+
+ SSVAL(outbuf,smb_vwv0,numentries);
+ SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
+ SCVAL(smb_buf(outbuf),0,5);
+ SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
+
+ if (Protocol >= PROTOCOL_NT1)
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
+
+ outsize += DIR_STRUCT_SIZE*numentries;
+ smb_setlen(outbuf,outsize - 4);
+
+ if ((! *directory) && dptr_path(dptr_num))
+ 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 ) );
+
+ END_PROFILE(SMBsearch);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a fclose (stop directory search).
+****************************************************************************/
+
+int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = 0;
+ int status_len;
+ char *path;
+ char status[21];
+ int dptr_num= -2;
+ START_PROFILE(SMBfclose);
+
+ outsize = set_message(outbuf,1,0,True);
+ path = smb_buf(inbuf) + 1;
+ status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
+
+
+ if (status_len == 0) {
+ END_PROFILE(SMBfclose);
+ return ERROR_DOS(ERRSRV,ERRsrverror);
+ }
+
+ memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
+
+ if(dptr_fetch(status+12,&dptr_num)) {
+ /* Close the dptr - we know it's gone */
+ dptr_close(&dptr_num);
+ }
+
+ SSVAL(outbuf,smb_vwv0,0);
+
+ DEBUG(3,("search close\n"));
+
+ END_PROFILE(SMBfclose);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to an open.
+****************************************************************************/
+
+int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ pstring fname;
+ int outsize = 0;
+ int fmode=0;
+ int share_mode;
+ SMB_OFF_T size = 0;
+ time_t mtime=0;
+ mode_t unixmode;
+ int rmode=0;
+ SMB_STRUCT_STAT sbuf;
+ BOOL bad_path = False;
+ files_struct *fsp;
+ int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ START_PROFILE(SMBopen);
+
+ share_mode = SVAL(inbuf,smb_vwv0);
+
+ pstrcpy(fname,smb_buf(inbuf)+1);
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+
+ unixmode = unix_mode(conn,aARCH,fname);
+
+ fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ unixmode, oplock_request,&rmode,NULL);
+
+ if (!fsp)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBopen);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ size = sbuf.st_size;
+ fmode = dos_mode(conn,fname,&sbuf);
+ mtime = sbuf.st_mtime;
+
+ if (fmode & aDIR) {
+ DEBUG(3,("attempt to open a directory %s\n",fname));
+ close_file(fsp,False);
+ END_PROFILE(SMBopen);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ outsize = set_message(outbuf,7,0,True);
+ SSVAL(outbuf,smb_vwv0,fsp->fnum);
+ SSVAL(outbuf,smb_vwv1,fmode);
+ if(lp_dos_filetime_resolution(SNUM(conn)) )
+ put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
+ else
+ put_dos_date3(outbuf,smb_vwv2,mtime);
+ SIVAL(outbuf,smb_vwv4,(uint32)size);
+ SSVAL(outbuf,smb_vwv6,rmode);
+
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ SCVAL(outbuf,smb_flg, CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
+
+ if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ SCVAL(outbuf,smb_flg, CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ END_PROFILE(SMBopen);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to an open and X.
+****************************************************************************/
+
+int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+{
+ pstring fname;
+ int smb_mode = SVAL(inbuf,smb_vwv3);
+ int smb_attr = SVAL(inbuf,smb_vwv5);
+ /* Breakout the oplock request bits so we can set the
+ reply bits separately. */
+ BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
+ BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ BOOL oplock_request = ex_oplock_request | core_oplock_request;
+#if 0
+ int open_flags = SVAL(inbuf,smb_vwv2);
+ int smb_sattr = SVAL(inbuf,smb_vwv4);
+ uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
+#endif
+ int smb_ofun = SVAL(inbuf,smb_vwv8);
+ mode_t unixmode;
+ SMB_OFF_T size=0;
+ int fmode=0,mtime=0,rmode=0;
+ SMB_STRUCT_STAT sbuf;
+ int smb_action = 0;
+ BOOL bad_path = False;
+ files_struct *fsp;
+ START_PROFILE(SMBopenX);
+
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn)) {
+ if (lp_nt_pipe_support()) {
+ END_PROFILE(SMBopenX);
+ return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
+ } else {
+ END_PROFILE(SMBopenX);
+ return ERROR_DOS(ERRSRV,ERRaccess);
+ }
+ }
+
+ /* XXXX we need to handle passed times, sattr and flags */
+
+ pstrcpy(fname,smb_buf(inbuf));
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+
+ unixmode = unix_mode(conn,smb_attr | aARCH, fname);
+
+ fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
+ oplock_request, &rmode,&smb_action);
+
+ if (!fsp)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBopenX);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ size = sbuf.st_size;
+ fmode = dos_mode(conn,fname,&sbuf);
+ mtime = sbuf.st_mtime;
+ if (fmode & aDIR) {
+ close_file(fsp,False);
+ END_PROFILE(SMBopenX);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ /* If the caller set the extended oplock request bit
+ and we granted one (by whatever means) - set the
+ correct bit for extended oplock reply.
+ */
+
+ if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+ }
+
+ if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+ }
+
+ /* If the caller set the core oplock request bit
+ and we granted one (by whatever means) - set the
+ correct bit for core oplock reply.
+ */
+
+ if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ SCVAL(outbuf,smb_flg, CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
+
+ if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
+
+ set_message(outbuf,15,0,True);
+ SSVAL(outbuf,smb_vwv2,fsp->fnum);
+ SSVAL(outbuf,smb_vwv3,fmode);
+ if(lp_dos_filetime_resolution(SNUM(conn)) )
+ put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
+ else
+ put_dos_date3(outbuf,smb_vwv4,mtime);
+ SIVAL(outbuf,smb_vwv6,(uint32)size);
+ SSVAL(outbuf,smb_vwv8,rmode);
+ SSVAL(outbuf,smb_vwv11,smb_action);
+
+ END_PROFILE(SMBopenX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
+}
+
+/****************************************************************************
+ Reply to a SMBulogoffX.
+****************************************************************************/
+
+int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+{
+ uint16 vuid = SVAL(inbuf,smb_uid);
+ user_struct *vuser = get_valid_user_struct(vuid);
+ START_PROFILE(SMBulogoffX);
+
+ if(vuser == 0) {
+ DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
+ }
+
+ /* in user level security we are supposed to close any files
+ open by this user */
+ if ((vuser != 0) && (lp_security() != SEC_SHARE)) {
+ file_close_user(vuid);
+ }
+
+ invalidate_vuid(vuid);
+
+ set_message(outbuf,2,0,True);
+
+ DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
+
+ END_PROFILE(SMBulogoffX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
+}
+
+/****************************************************************************
+ Reply to a mknew or a create.
+****************************************************************************/
+
+int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ pstring fname;
+ int com;
+ int outsize = 0;
+ int createmode;
+ mode_t unixmode;
+ int ofun = 0;
+ BOOL bad_path = False;
+ files_struct *fsp;
+ int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ SMB_STRUCT_STAT sbuf;
+ START_PROFILE(SMBcreate);
+
+ com = SVAL(inbuf,smb_com);
+
+ createmode = SVAL(inbuf,smb_vwv0);
+ pstrcpy(fname,smb_buf(inbuf)+1);
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+
+ if (createmode & aVOLID) {
+ DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
+ }
+
+ unixmode = unix_mode(conn,createmode,fname);
+
+ if(com == SMBmknew)
+ {
+ /* We should fail if file exists. */
+ ofun = FILE_CREATE_IF_NOT_EXIST;
+ }
+ else
+ {
+ /* SMBcreate - Create if file doesn't exist, truncate if it does. */
+ ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
+ }
+
+ /* Open file in dos compatibility share mode. */
+ fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
+ ofun, unixmode, oplock_request, NULL, NULL);
+
+ if (!fsp)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBcreate);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ outsize = set_message(outbuf,1,0,True);
+ SSVAL(outbuf,smb_vwv0,fsp->fnum);
+
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
+
+ if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+
+ DEBUG( 2, ( "new file %s\n", fname ) );
+ DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n",
+ fname, fsp->fd, createmode, (int)unixmode ) );
+
+ END_PROFILE(SMBcreate);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a create temporary file.
+****************************************************************************/
+
+int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ pstring fname;
+ int outsize = 0;
+ int createmode;
+ mode_t unixmode;
+ BOOL bad_path = False;
+ files_struct *fsp;
+ int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ int tmpfd;
+ SMB_STRUCT_STAT sbuf;
+ char *p, *s;
+
+ START_PROFILE(SMBctemp);
+
+ createmode = SVAL(inbuf,smb_vwv0);
+ pstrcpy(fname,smb_buf(inbuf)+1);
+ pstrcat(fname,"\\TMXXXXXX");
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+
+ unixmode = unix_mode(conn,createmode,fname);
+
+ tmpfd = smb_mkstemp(fname);
+ if (tmpfd == -1) {
+ END_PROFILE(SMBctemp);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ vfs_stat(conn,fname,&sbuf);
+
+ /* Open file in dos compatibility share mode. */
+ /* We should fail if file does not exist. */
+ fsp = open_file_shared(conn,fname,&sbuf,
+ SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
+ FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
+ unixmode, oplock_request, NULL, NULL);
+ /* close fd from smb_mkstemp() */
+ close(tmpfd);
+
+ if (!fsp) {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBctemp);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ /* the returned filename is relative to the directory */
+ s = strrchr(fname, '/');
+ if (!s)
+ s = fname;
+ else
+ s++;
+
+ outsize = set_message(outbuf,1,4+ strlen(fname),True);
+ SSVAL(outbuf,smb_vwv0,fsp->fnum);
+
+ p = smb_buf(outbuf);
+ SSVALS(p, 0, -1); /* what is this? not in spec */
+ SSVAL(p, 2, strlen(s));
+ p += 4;
+ pstrcpy(p,s);
+
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
+
+ if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+
+ DEBUG( 2, ( "created temp file %s\n", fname ) );
+ DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
+ fname, fsp->fd, createmode, (int)unixmode ) );
+
+ END_PROFILE(SMBctemp);
+ return(outsize);
+}
+
+/*******************************************************************
+ Check if a user is allowed to rename a file.
+********************************************************************/
+
+static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT *pst)
+{
+ int smb_action;
+ int access_mode;
+ files_struct *fsp;
+
+ if (!CAN_WRITE(conn))
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+
+ if (S_ISDIR(pst->st_mode))
+ return NT_STATUS_OK;
+
+ /* We need a better way to return NT status codes from open... */
+ unix_ERR_class = 0;
+ unix_ERR_code = 0;
+
+ fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
+
+ if (!fsp) {
+ NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
+ if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
+ ret = unix_ERR_ntstatus;
+ else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
+ ret = NT_STATUS_SHARING_VIOLATION;
+ unix_ERR_class = 0;
+ unix_ERR_code = 0;
+ unix_ERR_ntstatus = NT_STATUS_OK;
+ return ret;
+ }
+ close_file(fsp,False);
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Check if a user is allowed to delete a file.
+********************************************************************/
+
+static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
+{
+ SMB_STRUCT_STAT sbuf;
+ int fmode;
+ int smb_action;
+ int access_mode;
+ files_struct *fsp;
+
+ if (!CAN_WRITE(conn))
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+
+ if (conn->vfs_ops.lstat(conn,dos_to_unix_static(fname),&sbuf) != 0)
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ fmode = dos_mode(conn,fname,&sbuf);
+ if (fmode & aDIR)
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
+ if (!lp_delete_readonly(SNUM(conn))) {
+ if (fmode & aRONLY)
+ return NT_STATUS_CANNOT_DELETE;
+ }
+
+ if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
+ return NT_STATUS_CANNOT_DELETE;
+
+ /* We need a better way to return NT status codes from open... */
+ unix_ERR_class = 0;
+ unix_ERR_code = 0;
+
+ fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
+
+ if (!fsp) {
+ NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
+ if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
+ ret = NT_STATUS_SHARING_VIOLATION;
+ unix_ERR_class = 0;
+ unix_ERR_code = 0;
+ return ret;
+ }
+ close_file(fsp,False);
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ The guts of the unlink command, split out so it may be called by the NT SMB
+ code.
+****************************************************************************/
+
+NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
+{
+ pstring directory;
+ pstring mask;
+ char *p;
+ int count=0;
+ NTSTATUS error = NT_STATUS_OK;
+ BOOL has_wild;
+ BOOL bad_path = False;
+ BOOL rc = True;
+ SMB_STRUCT_STAT sbuf;
+
+ *directory = *mask = 0;
+
+ rc = unix_convert(name,conn,0,&bad_path,&sbuf);
+
+ p = strrchr(name,'/');
+ if (!p) {
+ pstrcpy(directory,".");
+ pstrcpy(mask,name);
+ } else {
+ *p = 0;
+ pstrcpy(directory,name);
+ pstrcpy(mask,p+1);
+ }
+
+ /*
+ * 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 && mangle_is_mangled(mask))
+ mangle_check_cache( mask, sizeof(pstring)-1 );
+
+ has_wild = ms_has_wild(mask);
+
+ if (!has_wild) {
+ pstrcat(directory,"/");
+ pstrcat(directory,mask);
+ error = can_delete(directory,conn,dirtype);
+ if (!NT_STATUS_IS_OK(error))
+ return error;
+
+ if (vfs_unlink(conn,directory) == 0)
+ count++;
+ } else {
+ void *dirptr = NULL;
+ char *dname;
+ if (check_name(directory,conn))
+ dirptr = OpenDir(conn, directory, True);
+
+ /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
+ the pattern matches against the long name, otherwise the short name
+ We don't implement this yet XXXX
+ */
+
+ if (dirptr) {
+ error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ if (strequal(mask,"????????.???"))
+ pstrcpy(mask,"*");
+
+ while ((dname = ReadDirName(dirptr))) {
+ pstring fname;
+ pstrcpy(fname,dname);
+
+ if(!mask_match(fname, mask, case_sensitive))
+ continue;
+
+ slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
+ error = can_delete(fname,conn,dirtype);
+ if (!NT_STATUS_IS_OK(error))
+ continue;
+ if (vfs_unlink(conn,fname) == 0)
+ count++;
+ DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
+ }
+ CloseDir(dirptr);
+ }
+ }
+
+ if (count == 0 && NT_STATUS_IS_OK(error))
+ error = map_nt_error_from_unix(errno);
+
+ return error;
+}
+
+/****************************************************************************
+ Reply to a unlink
+****************************************************************************/
+
+int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = 0;
+ pstring name;
+ int dirtype;
+ NTSTATUS status;
+
+ START_PROFILE(SMBunlink);
+
+ dirtype = SVAL(inbuf,smb_vwv0);
+
+ pstrcpy(name,smb_buf(inbuf) + 1);
+
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+
+ DEBUG(3,("reply_unlink : %s\n",name));
+
+ status = unlink_internals(conn, dirtype, name);
+ if (!NT_STATUS_IS_OK(status))
+ return ERROR_NT(status);
+
+ /*
+ * Win2k needs a changenotify request response before it will
+ * update after a rename..
+ */
+
+ process_pending_change_notify_queue((time_t)0);
+
+ outsize = set_message(outbuf,0,0,True);
+
+ END_PROFILE(SMBunlink);
+ return outsize;
+}
+
+/****************************************************************************
+ Fail for readbraw.
+****************************************************************************/
+
+void fail_readraw(void)
+{
+ pstring errstr;
+ slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
+ strerror(errno) );
+ exit_server(errstr);
+}
+
+/****************************************************************************
+ Use sendfile in readbraw.
+****************************************************************************/
+
+void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
+ ssize_t mincount, char *outbuf)
+{
+ ssize_t ret=0;
+
+#if defined(WITH_SENDFILE)
+ /*
+ * We can only use sendfile on a non-chained packet and on a file
+ * that is exclusively oplocked. reply_readbraw has already checked the length.
+ */
+
+ if ((nread > 0) && (lp_write_cache_size(SNUM(conn)) == 0) &&
+ EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_use_sendfile(SNUM(conn)) ) {
+ DATA_BLOB header;
+
+ _smb_setlen(outbuf,nread);
+ header.data = outbuf;
+ header.length = 4;
+ header.free = NULL;
+
+ if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
+ /*
+ * Special hack for broken Linux with no 64 bit clean sendfile. If we
+ * return ENOSYS then pretend we just got a normal read.
+ */
+ if (errno == ENOSYS)
+ goto normal_read;
+
+ DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
+ fsp->fsp_name, strerror(errno) ));
+ exit_server("send_file_readbraw sendfile failed");
+ }
+
+ }
+
+ normal_read:
+#endif
+
+ if (nread > 0) {
+ ret = read_file(fsp,outbuf+4,startpos,nread);
+ if (ret < mincount)
+ ret = 0;
+ }
+
+ _smb_setlen(outbuf,ret);
+ if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
+ fail_readraw();
+}
+
+/****************************************************************************
+ Reply to a readbraw (core+ protocol).
+****************************************************************************/
+
+int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
+{
+ ssize_t maxcount,mincount;
+ size_t nread = 0;
+ SMB_OFF_T startpos;
+ char *header = outbuf;
+ files_struct *fsp;
+ START_PROFILE(SMBreadbraw);
+
+ /*
+ * Special check if an oplock break has been issued
+ * and the readraw request croses on the wire, we must
+ * return a zero length response here.
+ */
+
+ if(global_oplock_break) {
+ _smb_setlen(header,0);
+ if (write_data(smbd_server_fd(),header,4) != 4)
+ fail_readraw();
+ DEBUG(5,("readbraw - oplock break finished\n"));
+ END_PROFILE(SMBreadbraw);
+ return -1;
+ }
+
+ 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);
+ if (write_data(smbd_server_fd(),header,4) != 4)
+ fail_readraw();
+ END_PROFILE(SMBreadbraw);
+ return(-1);
+ }
+
+ CHECK_FSP(fsp,conn);
+
+ flush_write_cache(fsp, READRAW_FLUSH);
+
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
+ 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);
+ if (write_data(smbd_server_fd(),header,4) != 4)
+ fail_readraw();
+ END_PROFILE(SMBreadbraw);
+ return(-1);
+ }
+
+#endif /* LARGE_SMB_OFF_T */
+
+ if(startpos < 0) {
+ DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
+ _smb_setlen(header,0);
+ if (write_data(smbd_server_fd(),header,4) != 4)
+ fail_readraw();
+ END_PROFILE(SMBreadbraw);
+ return(-1);
+ }
+ }
+ maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
+ mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
+
+ /* ensure we don't overrun the packet size */
+ maxcount = MIN(65535,maxcount);
+ maxcount = MAX(mincount,maxcount);
+
+ if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ SMB_OFF_T size = fsp->size;
+ SMB_OFF_T sizeneeded = startpos + maxcount;
+
+ if (size < sizeneeded) {
+ SMB_STRUCT_STAT st;
+ if (vfs_fstat(fsp,fsp->fd,&st) == 0)
+ fsp->size = size = st.st_size;
+ }
+
+ if (startpos >= size)
+ nread = 0;
+ else
+ nread = MIN(maxcount,(size - startpos));
+ }
+
+ if (nread < mincount)
+ nread = 0;
+
+ DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
+ (int)maxcount, (int)mincount, (int)nread ) );
+
+ send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf);
+
+ DEBUG(5,("readbraw finished\n"));
+ END_PROFILE(SMBreadbraw);
+ return -1;
+}
+
+/****************************************************************************
+ Reply to a lockread (core+ protocol).
+****************************************************************************/
+
+int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
+{
+ ssize_t nread = -1;
+ char *data;
+ int outsize = 0;
+ SMB_OFF_T startpos;
+ size_t numtoread;
+ NTSTATUS status;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBlockread);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_READ(fsp);
+
+ release_level_2_oplocks_on_change(fsp);
+
+ numtoread = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
+
+ outsize = set_message(outbuf,5,3,True);
+ numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
+ data = smb_buf(outbuf) + 3;
+
+ /*
+ * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
+ * protocol request that predates the read/write lock concept.
+ * Thus instead of asking for a read lock here we need to ask
+ * for a write lock. JRA.
+ */
+
+ status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid),
+ (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK);
+
+ if (NT_STATUS_V(status)) {
+ if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
+ /*
+ * A blocking lock was requested. Package up
+ * this smb into a queued request and push it
+ * onto the blocking lock queue.
+ */
+ if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)startpos,
+ (SMB_BIG_UINT)numtoread)) {
+ END_PROFILE(SMBlockread);
+ return -1;
+ }
+ }
+ END_PROFILE(SMBlockread);
+ return ERROR_NT(status);
+ }
+
+ nread = read_file(fsp,data,startpos,numtoread);
+
+ if (nread < 0) {
+ END_PROFILE(SMBlockread);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ outsize += nread;
+ SSVAL(outbuf,smb_vwv0,nread);
+ SSVAL(outbuf,smb_vwv5,nread+3);
+ SSVAL(smb_buf(outbuf),1,nread);
+
+ DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n",
+ fsp->fnum, (int)numtoread, (int)nread ) );
+
+ END_PROFILE(SMBlockread);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a read.
+****************************************************************************/
+
+int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+{
+ size_t numtoread;
+ ssize_t nread = 0;
+ char *data;
+ SMB_OFF_T startpos;
+ int outsize = 0;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBread);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_READ(fsp);
+
+ numtoread = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
+
+ outsize = set_message(outbuf,5,3,True);
+ numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
+ data = smb_buf(outbuf) + 3;
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ END_PROFILE(SMBread);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
+
+ if (numtoread > 0)
+ nread = read_file(fsp,data,startpos,numtoread);
+
+ if (nread < 0) {
+ END_PROFILE(SMBread);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ outsize += nread;
+ SSVAL(outbuf,smb_vwv0,nread);
+ SSVAL(outbuf,smb_vwv5,nread+3);
+ SCVAL(smb_buf(outbuf),0,1);
+ SSVAL(smb_buf(outbuf),1,nread);
+
+ DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
+ fsp->fnum, (int)numtoread, (int)nread ) );
+
+ END_PROFILE(SMBread);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a read and X - possibly using sendfile.
+****************************************************************************/
+
+int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length,
+ files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
+{
+ ssize_t nread = -1;
+ char *data = smb_buf(outbuf);
+
+#if defined(WITH_SENDFILE)
+ /*
+ * We can only use sendfile on a non-chained packet and on a file
+ * that is exclusively oplocked.
+ */
+
+ if ((CVAL(inbuf,smb_vwv0) == 0xFF) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
+ lp_use_sendfile(SNUM(conn)) && (lp_write_cache_size(SNUM(conn)) == 0) ) {
+ SMB_STRUCT_STAT sbuf;
+ DATA_BLOB header;
+
+ if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+ if (startpos > sbuf.st_size)
+ goto normal_read;
+
+ if (smb_maxcnt > (sbuf.st_size - startpos))
+ smb_maxcnt = (sbuf.st_size - startpos);
+
+ if (smb_maxcnt == 0)
+ goto normal_read;
+
+ /*
+ * Set up the packet header before send. We
+ * assume here the sendfile will work (get the
+ * correct amount of data).
+ */
+
+ SSVAL(outbuf,smb_vwv5,smb_maxcnt);
+ SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
+ SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
+ SCVAL(outbuf,smb_vwv0,0xFF);
+ set_message(outbuf,12,smb_maxcnt,False);
+ header.data = outbuf;
+ header.length = data - outbuf;
+ header.free = NULL;
+
+ if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
+ /*
+ * Special hack for broken Linux with no 64 bit clean sendfile. If we
+ * return ENOSYS then pretend we just got a normal read.
+ */
+ if (errno == ENOSYS)
+ goto normal_read;
+
+ DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
+ fsp->fsp_name, strerror(errno) ));
+ exit_server("send_file_readX sendfile failed");
+ }
+
+ DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
+ fsp->fnum, (int)smb_maxcnt, (int)nread ) );
+ return -1;
+ }
+
+ normal_read:
+
+#endif
+
+ nread = read_file(fsp,data,startpos,smb_maxcnt);
+
+ if (nread < 0) {
+ END_PROFILE(SMBreadX);
+ 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, ( "send_file_readX fnum=%d max=%d nread=%d\n",
+ fsp->fnum, (int)smb_maxcnt, (int)nread ) );
+
+ return nread;
+}
+
+/****************************************************************************
+ Reply to a read and X.
+****************************************************************************/
+
+int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+{
+ files_struct *fsp = file_fsp(inbuf,smb_vwv2);
+ SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
+ size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
+#if 0
+ size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
+#endif
+ ssize_t nread = -1;
+ char *data;
+ START_PROFILE(SMBreadX);
+
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn)) {
+ END_PROFILE(SMBreadX);
+ return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
+ }
+
+ CHECK_FSP(fsp,conn);
+ CHECK_READ(fsp);
+
+ set_message(outbuf,12,0,True);
+ data = smb_buf(outbuf);
+
+ 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) ));
+ END_PROFILE(SMBreadX);
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
+ }
+
+#endif /* LARGE_SMB_OFF_T */
+
+ }
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ END_PROFILE(SMBreadX);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
+ nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt);
+ if (nread != -1)
+ nread = chain_reply(inbuf,outbuf,length,bufsize);
+
+ END_PROFILE(SMBreadX);
+ return nread;
+}
+
+/****************************************************************************
+ Reply to a writebraw (core+ or LANMAN1.0 protocol).
+****************************************************************************/
+
+int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+{
+ ssize_t nwritten=0;
+ ssize_t total_written=0;
+ size_t numtowrite=0;
+ size_t tcount;
+ SMB_OFF_T startpos;
+ char *data=NULL;
+ BOOL write_through;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ int outsize = 0;
+ START_PROFILE(SMBwritebraw);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ tcount = IVAL(inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
+ write_through = BITSETW(inbuf+smb_vwv7,0);
+
+ /* We have to deal with slightly different formats depending
+ on whether we are using the core+ or lanman1.0 protocol */
+
+ if(Protocol <= PROTOCOL_COREPLUS) {
+ numtowrite = SVAL(smb_buf(inbuf),-2);
+ data = smb_buf(inbuf);
+ } else {
+ numtowrite = SVAL(inbuf,smb_vwv10);
+ data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
+ }
+
+ /* force the error type */
+ SCVAL(inbuf,smb_com,SMBwritec);
+ SCVAL(outbuf,smb_com,SMBwritec);
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ END_PROFILE(SMBwritebraw);
+ return(ERROR_DOS(ERRDOS,ERRlock));
+ }
+
+ if (numtowrite>0)
+ 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, (int)numtowrite, (int)nwritten, (int)write_through));
+
+ if (nwritten < (ssize_t)numtowrite) {
+ END_PROFILE(SMBwritebraw);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
+
+ total_written = nwritten;
+
+ /* Return a message to the redirector to tell it to send more bytes */
+ SCVAL(outbuf,smb_com,SMBwritebraw);
+ SSVALS(outbuf,smb_vwv0,-1);
+ outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("reply_writebraw: send_smb failed.");
+
+ /* Now read the raw data into the buffer and write it */
+ if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
+ exit_server("secondary writebraw failed");
+ }
+
+ /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
+ numtowrite = smb_len(inbuf);
+
+ /* Set up outbuf to return the correct return */
+ outsize = set_message(outbuf,1,0,True);
+ SCVAL(outbuf,smb_com,SMBwritec);
+ SSVAL(outbuf,smb_vwv0,total_written);
+
+ if (numtowrite != 0) {
+
+ if (numtowrite > BUFFER_SIZE) {
+ DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
+ (unsigned int)numtowrite ));
+ exit_server("secondary writebraw failed");
+ }
+
+ if (tcount > nwritten+numtowrite) {
+ DEBUG(3,("Client overestimated the write %d %d %d\n",
+ (int)tcount,(int)nwritten,(int)numtowrite));
+ }
+
+ if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
+ DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
+ strerror(errno) ));
+ exit_server("secondary writebraw failed");
+ }
+
+ nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
+
+ if (nwritten < (ssize_t)numtowrite) {
+ SCVAL(outbuf,smb_rcls,ERRHRD);
+ SSVAL(outbuf,smb_err,ERRdiskfull);
+ }
+
+ if (nwritten > 0)
+ total_written += nwritten;
+ }
+
+ if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn)))
+ sync_file(conn,fsp);
+
+ DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
+ 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 */
+ END_PROFILE(SMBwritebraw);
+ if (!write_through && total_written==tcount) {
+ /*
+ * Fix for "rabbit pellet" mode, trigger an early TCP ack by
+ * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
+ */
+ if (!send_keepalive(smbd_server_fd()))
+ exit_server("reply_writebraw: send of keepalive failed");
+ return(-1);
+ }
+
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a writeunlock (core+).
+****************************************************************************/
+
+int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+{
+ ssize_t nwritten = -1;
+ size_t numtowrite;
+ SMB_OFF_T startpos;
+ char *data;
+ NTSTATUS status;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ int outsize = 0;
+ START_PROFILE(SMBwriteunlock);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ numtowrite = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
+ data = smb_buf(inbuf) + 3;
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
+ WRITE_LOCK,False)) {
+ END_PROFILE(SMBwriteunlock);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
+
+ /* 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,startpos,numtowrite);
+
+ if (lp_syncalways(SNUM(conn)))
+ sync_file(conn,fsp);
+
+ if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ END_PROFILE(SMBwriteunlock);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
+
+ status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
+ (SMB_BIG_UINT)startpos);
+ if (NT_STATUS_V(status)) {
+ END_PROFILE(SMBwriteunlock);
+ return ERROR_NT(status);
+ }
+
+ outsize = set_message(outbuf,1,0,True);
+
+ SSVAL(outbuf,smb_vwv0,nwritten);
+
+ DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n",
+ fsp->fnum, (int)numtowrite, (int)nwritten ) );
+
+ END_PROFILE(SMBwriteunlock);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a write.
+****************************************************************************/
+
+int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
+{
+ size_t numtowrite;
+ ssize_t nwritten = -1;
+ SMB_OFF_T startpos;
+ char *data;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ int outsize = 0;
+ START_PROFILE(SMBwrite);
+
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn)) {
+ END_PROFILE(SMBwrite);
+ return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
+ }
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ numtowrite = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
+ data = smb_buf(inbuf) + 3;
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ END_PROFILE(SMBwrite);
+ return ERROR_DOS(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) {
+ /*
+ * This is actually an allocate call, and set EOF. JRA.
+ */
+ nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
+ if (nwritten < 0) {
+ END_PROFILE(SMBwrite);
+ return ERROR_NT(NT_STATUS_DISK_FULL);
+ }
+ nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
+ if (nwritten < 0) {
+ END_PROFILE(SMBwrite);
+ return ERROR_NT(NT_STATUS_DISK_FULL);
+ }
+ } else
+ nwritten = write_file(fsp,data,startpos,numtowrite);
+
+ if (lp_syncalways(SNUM(conn)))
+ sync_file(conn,fsp);
+
+ if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ END_PROFILE(SMBwrite);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
+
+ outsize = set_message(outbuf,1,0,True);
+
+ SSVAL(outbuf,smb_vwv0,nwritten);
+
+ if (nwritten < (ssize_t)numtowrite) {
+ SCVAL(outbuf,smb_rcls,ERRHRD);
+ SSVAL(outbuf,smb_err,ERRdiskfull);
+ }
+
+ DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
+
+ END_PROFILE(SMBwrite);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a write and X.
+****************************************************************************/
+
+int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+{
+ files_struct *fsp = file_fsp(inbuf,smb_vwv2);
+ SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
+ size_t numtowrite = SVAL(inbuf,smb_vwv10);
+ BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
+ ssize_t nwritten = -1;
+ unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
+ unsigned int smblen = smb_len(inbuf);
+ char *data;
+ BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
+ START_PROFILE(SMBwriteX);
+
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn)) {
+ END_PROFILE(SMBwriteX);
+ return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
+ }
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ /* Deal with possible LARGE_WRITEX */
+ if (large_writeX)
+ numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
+
+ if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
+ END_PROFILE(SMBwriteX);
+ return ERROR_DOS(ERRDOS,ERRbadmem);
+ }
+
+ data = smb_base(inbuf) + smb_doff;
+
+ 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) ));
+ END_PROFILE(SMBwriteX);
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
+ }
+
+#endif /* LARGE_SMB_OFF_T */
+ }
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ END_PROFILE(SMBwriteX);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
+
+ /* 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,
+ use SMBwrite. */
+ if(numtowrite == 0)
+ nwritten = 0;
+ else
+ nwritten = write_file(fsp,data,startpos,numtowrite);
+
+ if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ END_PROFILE(SMBwriteX);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
+
+ set_message(outbuf,6,0,True);
+
+ SSVAL(outbuf,smb_vwv2,nwritten);
+ if (large_writeX)
+ SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
+
+ if (nwritten < (ssize_t)numtowrite) {
+ SCVAL(outbuf,smb_rcls,ERRHRD);
+ SSVAL(outbuf,smb_err,ERRdiskfull);
+ }
+
+ DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
+ fsp->fnum, (int)numtowrite, (int)nwritten));
+
+ if (lp_syncalways(SNUM(conn)) || write_through)
+ sync_file(conn,fsp);
+
+ END_PROFILE(SMBwriteX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
+}
+
+
+/****************************************************************************
+ Reply to a lseek.
+****************************************************************************/
+
+int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+{
+ SMB_OFF_T startpos;
+ SMB_OFF_T res= -1;
+ int mode,umode;
+ int outsize = 0;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBlseek);
+
+ CHECK_FSP(fsp,conn);
+
+ flush_write_cache(fsp, SEEK_FLUSH);
+
+ mode = SVAL(inbuf,smb_vwv1) & 3;
+ /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
+ startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
+
+ switch (mode) {
+ case 0: umode = SEEK_SET; break;
+ case 1: umode = SEEK_CUR; break;
+ case 2: umode = SEEK_END; break;
+ default:
+ umode = SEEK_SET; break;
+ }
+
+ if((res = conn->vfs_ops.lseek(fsp,fsp->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 = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) {
+ END_PROFILE(SMBlseek);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ current_pos += startpos;
+
+ } else if (umode == SEEK_END) {
+
+ SMB_STRUCT_STAT sbuf;
+
+ if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) {
+ END_PROFILE(SMBlseek);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ current_pos += sbuf.st_size;
+ }
+
+ if(current_pos < 0)
+ res = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_SET);
+ }
+
+ if(res == -1) {
+ END_PROFILE(SMBlseek);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ }
+
+ fsp->pos = res;
+
+ outsize = set_message(outbuf,2,0,True);
+ SIVAL(outbuf,smb_vwv0,res);
+
+ DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
+ fsp->fnum, (double)startpos, (double)res, mode));
+
+ END_PROFILE(SMBlseek);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a flush.
+****************************************************************************/
+
+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);
+ START_PROFILE(SMBflush);
+
+ CHECK_FSP(fsp,conn);
+
+ if (!fsp) {
+ file_sync_all(conn);
+ } else {
+ sync_file(conn,fsp);
+ }
+
+ DEBUG(3,("flush\n"));
+ END_PROFILE(SMBflush);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a exit.
+****************************************************************************/
+
+int reply_exit(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize;
+ START_PROFILE(SMBexit);
+ outsize = set_message(outbuf,0,0,True);
+
+ DEBUG(3,("exit\n"));
+
+ END_PROFILE(SMBexit);
+ return(outsize);
+}
+
+
+/****************************************************************************
+ 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 size,
+ int dum_buffsize)
+{
+ int outsize = 0;
+ time_t mtime;
+ files_struct *fsp = NULL;
+ START_PROFILE(SMBclose);
+
+ outsize = set_message(outbuf,0,0,True);
+
+ /* If it's an IPC, pass off to the pipe handler. */
+ if (IS_IPC(conn)) {
+ END_PROFILE(SMBclose);
+ return reply_pipe_close(conn, inbuf,outbuf);
+ }
+
+ fsp = file_fsp(inbuf,smb_vwv0);
+
+ /*
+ * We can only use CHECK_FSP if we know it's not a directory.
+ */
+
+ if(!fsp || (fsp->conn != conn)) {
+ END_PROFILE(SMBclose);
+ return ERROR_DOS(ERRDOS,ERRbadfid);
+ }
+
+ if(fsp->is_directory) {
+ /*
+ * Special case - close NT SMB directory handle.
+ */
+ 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;
+ pstring file_name;
+
+ /* Save the name for time set in close. */
+ pstrcpy( file_name, fsp->fsp_name);
+
+ DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
+ fsp->fd, fsp->fnum,
+ conn->num_files_open));
+
+ /*
+ * 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;
+ END_PROFILE(SMBclose);
+ return (UNIXERROR(ERRHRD,ERRgeneral));
+ }
+
+ /*
+ * Now take care of any time sent in the close.
+ */
+
+ mtime = make_unix_date3(inbuf+smb_vwv1);
+
+ /* try and set the date */
+ set_filetime(conn, file_name, mtime);
+
+ }
+
+ END_PROFILE(SMBclose);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a writeclose (Core+ protocol)
+****************************************************************************/
+
+int reply_writeclose(connection_struct *conn,
+ 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;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBwriteclose);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ numtowrite = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
+ mtime = make_unix_date3(inbuf+smb_vwv4);
+ data = smb_buf(inbuf) + 1;
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ END_PROFILE(SMBwriteclose);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
+
+ nwritten = write_file(fsp,data,startpos,numtowrite);
+
+ set_filetime(conn, fsp->fsp_name,mtime);
+
+ close_err = close_file(fsp,True);
+
+ DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
+ fsp->fnum, (int)numtowrite, (int)nwritten,
+ conn->num_files_open));
+
+ if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ END_PROFILE(SMBwriteclose);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
+
+ if(close_err != 0) {
+ errno = close_err;
+ END_PROFILE(SMBwriteclose);
+ return(UNIXERROR(ERRHRD,ERRgeneral));
+ }
+
+ outsize = set_message(outbuf,1,0,True);
+
+ SSVAL(outbuf,smb_vwv0,nwritten);
+ END_PROFILE(SMBwriteclose);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a lock.
+****************************************************************************/
+
+int reply_lock(connection_struct *conn,
+ char *inbuf,char *outbuf, int length, int dum_buffsize)
+{
+ int outsize = set_message(outbuf,0,0,True);
+ SMB_BIG_UINT count,offset;
+ NTSTATUS status;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBlock);
+
+ CHECK_FSP(fsp,conn);
+
+ release_level_2_oplocks_on_change(fsp);
+
+ count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
+ offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
+
+ DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
+ fsp->fd, fsp->fnum, (double)offset, (double)count));
+
+ status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK);
+ if (NT_STATUS_V(status)) {
+ if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
+ /*
+ * A blocking lock was requested. Package up
+ * this smb into a queued request and push it
+ * onto the blocking lock queue.
+ */
+ if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), offset, count)) {
+ END_PROFILE(SMBlock);
+ return -1;
+ }
+ }
+ END_PROFILE(SMBlock);
+ return ERROR_NT(status);
+ }
+
+ END_PROFILE(SMBlock);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a unlock.
+****************************************************************************/
+
+int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+{
+ int outsize = set_message(outbuf,0,0,True);
+ SMB_BIG_UINT count,offset;
+ NTSTATUS status;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBunlock);
+
+ CHECK_FSP(fsp,conn);
+
+ count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
+ offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
+
+ status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
+ if (NT_STATUS_V(status)) {
+ END_PROFILE(SMBunlock);
+ return ERROR_NT(status);
+ }
+
+ DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
+ fsp->fd, fsp->fnum, (double)offset, (double)count ) );
+
+ END_PROFILE(SMBunlock);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a tdis.
+****************************************************************************/
+
+int reply_tdis(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = set_message(outbuf,0,0,True);
+ uint16 vuid;
+ START_PROFILE(SMBtdis);
+
+ vuid = SVAL(inbuf,smb_uid);
+
+ if (!conn) {
+ DEBUG(4,("Invalid connection in tdis\n"));
+ END_PROFILE(SMBtdis);
+ return ERROR_DOS(ERRSRV,ERRinvnid);
+ }
+
+ conn->used = False;
+
+ close_cnum(conn,vuid);
+
+ END_PROFILE(SMBtdis);
+ return outsize;
+}
+
+/****************************************************************************
+ Reply to a echo.
+****************************************************************************/
+
+int reply_echo(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int smb_reverb = SVAL(inbuf,smb_vwv0);
+ int seq_num;
+ unsigned int data_len = smb_buflen(inbuf);
+ int outsize = set_message(outbuf,1,data_len,True);
+ START_PROFILE(SMBecho);
+
+ data_len = MIN(data_len, (sizeof(inbuf)-(smb_buf(inbuf)-inbuf)));
+
+ /* copy any incoming data back out */
+ if (data_len > 0)
+ memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
+
+ if (smb_reverb > 100) {
+ DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
+ smb_reverb = 100;
+ }
+
+ for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
+ SSVAL(outbuf,smb_vwv0,seq_num);
+
+ smb_setlen(outbuf,outsize - 4);
+
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("reply_echo: send_smb failed.");
+ }
+
+ DEBUG(3,("echo %d times\n", smb_reverb));
+
+ smb_echo_count++;
+
+ END_PROFILE(SMBecho);
+ return -1;
+}
+
+/****************************************************************************
+ Reply to a printopen.
+****************************************************************************/
+
+int reply_printopen(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = 0;
+ files_struct *fsp;
+ START_PROFILE(SMBsplopen);
+
+ if (!CAN_PRINT(conn)) {
+ END_PROFILE(SMBsplopen);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ /* Open for exclusive use, write only. */
+ fsp = print_fsp_open(conn, NULL);
+
+ if (!fsp) {
+ END_PROFILE(SMBsplopen);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ outsize = set_message(outbuf,1,0,True);
+ SSVAL(outbuf,smb_vwv0,fsp->fnum);
+
+ DEBUG(3,("openprint fd=%d fnum=%d\n",
+ fsp->fd, fsp->fnum));
+
+ END_PROFILE(SMBsplopen);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a printclose.
+****************************************************************************/
+
+int reply_printclose(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = set_message(outbuf,0,0,True);
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ int close_err = 0;
+ START_PROFILE(SMBsplclose);
+
+ CHECK_FSP(fsp,conn);
+
+ if (!CAN_PRINT(conn)) {
+ END_PROFILE(SMBsplclose);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ DEBUG(3,("printclose fd=%d fnum=%d\n",
+ fsp->fd,fsp->fnum));
+
+ close_err = close_file(fsp,True);
+
+ if(close_err != 0) {
+ errno = close_err;
+ END_PROFILE(SMBsplclose);
+ return(UNIXERROR(ERRHRD,ERRgeneral));
+ }
+
+ END_PROFILE(SMBsplclose);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a printqueue.
+****************************************************************************/
+
+int reply_printqueue(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = set_message(outbuf,2,3,True);
+ int max_count = SVAL(inbuf,smb_vwv0);
+ int start_index = SVAL(inbuf,smb_vwv1);
+ START_PROFILE(SMBsplretq);
+
+ /* we used to allow the client to get the cnum wrong, but that
+ is really quite gross and only worked when there was only
+ one printer - I think we should now only accept it if they
+ get it right (tridge) */
+ if (!CAN_PRINT(conn)) {
+ END_PROFILE(SMBsplretq);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ SSVAL(outbuf,smb_vwv0,0);
+ SSVAL(outbuf,smb_vwv1,0);
+ SCVAL(smb_buf(outbuf),0,1);
+ SSVAL(smb_buf(outbuf),1,0);
+
+ DEBUG(3,("printqueue start_index=%d max_count=%d\n",
+ start_index, max_count));
+
+ {
+ print_queue_struct *queue = NULL;
+ print_status_struct status;
+ char *p = smb_buf(outbuf) + 3;
+ int count = print_queue_status(SNUM(conn), &queue, &status);
+ int num_to_get = ABS(max_count);
+ int first = (max_count>0?start_index:start_index+max_count+1);
+ int i;
+
+ if (first >= count)
+ num_to_get = 0;
+ else
+ num_to_get = MIN(num_to_get,count-first);
+
+
+ for (i=first;i<first+num_to_get;i++) {
+ /* check to make sure we have room in the buffer */
+ if ( (PTR_DIFF(p, outbuf)+28) > BUFFER_SIZE )
+ break;
+ put_dos_date2(p,0,queue[i].time);
+ SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
+ SSVAL(p,5, queue[i].job);
+ SIVAL(p,7,queue[i].size);
+ SCVAL(p,11,0);
+ StrnCpy(p+12,queue[i].fs_user,16);
+ p += 28;
+ }
+
+ if (count > 0) {
+ outsize = set_message(outbuf,2,28*count+3,False);
+ SSVAL(outbuf,smb_vwv0,count);
+ SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
+ SCVAL(smb_buf(outbuf),0,1);
+ SSVAL(smb_buf(outbuf),1,28*count);
+ }
+
+ SAFE_FREE(queue);
+
+ DEBUG(3,("%d entries returned in queue\n",count));
+ }
+
+ END_PROFILE(SMBsplretq);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a printwrite.
+****************************************************************************/
+
+int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int numtowrite;
+ int outsize = set_message(outbuf,0,0,True);
+ char *data;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBsplwr);
+
+ if (!CAN_PRINT(conn)) {
+ END_PROFILE(SMBsplwr);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ numtowrite = SVAL(smb_buf(inbuf),1);
+ data = smb_buf(inbuf) + 3;
+
+ if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
+ END_PROFILE(SMBsplwr);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
+
+ DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
+
+ END_PROFILE(SMBsplwr);
+ return(outsize);
+}
+
+/****************************************************************************
+ The guts of the mkdir command, split out so it may be called by the NT SMB
+ code.
+****************************************************************************/
+
+NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
+{
+ BOOL bad_path = False;
+ SMB_STRUCT_STAT sbuf;
+ int ret= -1;
+
+ unix_convert(directory,conn,0,&bad_path,&sbuf);
+
+ if (check_name(directory, conn))
+ ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
+
+ if (ret == -1) {
+ NTSTATUS nterr = set_bad_path_error(errno, bad_path);
+ if (!NT_STATUS_IS_OK(nterr))
+ return nterr;
+ return map_nt_error_from_unix(errno);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a mkdir.
+****************************************************************************/
+
+int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ pstring directory;
+ int outsize;
+ NTSTATUS status;
+ START_PROFILE(SMBmkdir);
+
+ pstrcpy(directory,smb_buf(inbuf) + 1);
+
+ RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
+
+ status = mkdir_internal(conn, directory);
+ if (!NT_STATUS_IS_OK(status))
+ return ERROR_NT(status);
+
+ outsize = set_message(outbuf,0,0,True);
+
+ DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
+
+ END_PROFILE(SMBmkdir);
+ return(outsize);
+}
+
+/****************************************************************************
+ Static function used by reply_rmdir to delete an entire directory
+ tree recursively. Return False on ok, True on fail.
+****************************************************************************/
+
+static BOOL recursive_rmdir(connection_struct *conn, char *directory)
+{
+ char *dname = NULL;
+ BOOL ret = False;
+ void *dirptr = OpenDir(conn, directory, False);
+
+ if(dirptr == NULL)
+ return True;
+
+ 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;
+ ret = True;
+ break;
+ }
+
+ pstrcpy(fullname, directory);
+ pstrcat(fullname, "/");
+ pstrcat(fullname, dname);
+
+ if(conn->vfs_ops.lstat(conn,dos_to_unix_static(fullname), &st) != 0) {
+ ret = True;
+ break;
+ }
+
+ if(st.st_mode & S_IFDIR) {
+ if(recursive_rmdir(conn, fullname)!=0) {
+ ret = True;
+ break;
+ }
+ if(vfs_rmdir(conn,fullname) != 0) {
+ ret = True;
+ break;
+ }
+ } else if(vfs_unlink(conn,fullname) != 0) {
+ ret = True;
+ break;
+ }
+ }
+
+ CloseDir(dirptr);
+ return ret;
+}
+
+/****************************************************************************
+ The internals of the rmdir code - called elsewhere.
+****************************************************************************/
+
+BOOL rmdir_internals(connection_struct *conn, char *directory)
+{
+ BOOL ok;
+
+ ok = (vfs_rmdir(conn,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(conn->vfs_ops.lstat(conn,dos_to_unix_static(fullname), &st) != 0)
+ break;
+ if(st.st_mode & S_IFDIR) {
+ if(lp_recursive_veto_delete(SNUM(conn))) {
+ if(recursive_rmdir(conn, fullname) != 0)
+ break;
+ }
+ if(vfs_rmdir(conn,fullname) != 0)
+ break;
+ } else if(vfs_unlink(conn,fullname) != 0)
+ break;
+ }
+ CloseDir(dirptr);
+ /* Retry the rmdir */
+ ok = (vfs_rmdir(conn,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;
+ int outsize = 0;
+ BOOL ok = False;
+ BOOL bad_path = False;
+ SMB_STRUCT_STAT sbuf;
+ START_PROFILE(SMBrmdir);
+
+ pstrcpy(directory,smb_buf(inbuf) + 1);
+
+ RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
+
+ unix_convert(directory,conn, NULL,&bad_path,&sbuf);
+
+ if (check_name(directory,conn))
+ {
+ dptr_closepath(directory,SVAL(inbuf,smb_pid));
+ ok = rmdir_internals(conn, directory);
+ }
+
+ if (!ok)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBrmdir);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+
+ outsize = set_message(outbuf,0,0,True);
+
+ DEBUG( 3, ( "rmdir %s\n", directory ) );
+
+ END_PROFILE(SMBrmdir);
+ return(outsize);
+}
+
+/*******************************************************************
+ Resolve wildcards in a filename rename.
+********************************************************************/
+
+static BOOL resolve_wildcards(char *name1,char *name2)
+{
+ fstring root1,root2;
+ fstring ext1,ext2;
+ char *p,*p2;
+
+ name1 = strrchr(name1,'/');
+ name2 = strrchr(name2,'/');
+
+ if (!name1 || !name2) return(False);
+
+ fstrcpy(root1,name1);
+ fstrcpy(root2,name2);
+ p = strrchr(root1,'.');
+ if (p) {
+ *p = 0;
+ fstrcpy(ext1,p+1);
+ } else {
+ fstrcpy(ext1,"");
+ }
+ p = strrchr(root2,'.');
+ if (p) {
+ *p = 0;
+ fstrcpy(ext2,p+1);
+ } else {
+ fstrcpy(ext2,"");
+ }
+
+ p = root1;
+ p2 = root2;
+ while (*p2) {
+ if (*p2 == '?') {
+ *p2 = *p;
+ p2++;
+ } else {
+ p2++;
+ }
+ if (*p) p++;
+ }
+
+ p = ext1;
+ p2 = ext2;
+ while (*p2) {
+ if (*p2 == '?') {
+ *p2 = *p;
+ p2++;
+ } else {
+ p2++;
+ }
+ if (*p) p++;
+ }
+
+ pstrcpy(name2,root2);
+ if (ext2[0]) {
+ pstrcat(name2,".");
+ pstrcat(name2,ext2);
+ }
+
+ return(True);
+}
+
+/****************************************************************************
+ The guts of the rename command, split out so it may be called by the NT SMB
+ code.
+****************************************************************************/
+
+NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists)
+{
+ pstring directory;
+ pstring mask;
+ pstring newname_last_component;
+ char *p;
+ BOOL has_wild;
+ BOOL bad_path1 = False;
+ BOOL bad_path2 = False;
+ int count=0;
+ NTSTATUS error = NT_STATUS_OK;
+ BOOL rc = True;
+ SMB_STRUCT_STAT sbuf1, sbuf2;
+
+ *directory = *mask = 0;
+
+ rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
+ unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2);
+
+ /*
+ * Split the old name into directory and last component
+ * 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
+ * as this is checked in resolve_wildcards().
+ */
+
+ p = strrchr(name,'/');
+ if (!p) {
+ pstrcpy(directory,".");
+ pstrcpy(mask,name);
+ } else {
+ *p = 0;
+ pstrcpy(directory,name);
+ pstrcpy(mask,p+1);
+ *p = '/'; /* Replace needed for exceptional test below. */
+ }
+
+ /*
+ * 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 && mangle_is_mangled(mask))
+ mangle_check_cache( mask, sizeof(pstring)-1 );
+
+ has_wild = ms_has_wild(mask);
+
+ if (!has_wild) {
+ pstring zdirectory;
+ pstring znewname;
+
+ /*
+ * No wildcards - just process the one file.
+ */
+ BOOL is_short_name = mangle_is_8_3(name, True);
+
+ /* Add a terminating '/' to the directory name. */
+ pstrcat(directory,"/");
+ pstrcat(directory,mask);
+
+ /* Ensure newname contains a '/' also */
+ if(strrchr(newname,'/') == 0) {
+ pstring tmpstr;
+
+ pstrcpy(tmpstr, "./");
+ pstrcat(tmpstr, newname);
+ pstrcpy(newname, tmpstr);
+ }
+
+ DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
+directory = %s, newname = %s, newname_last_component = %s, mangle_is_8_3 = %d\n",
+ case_sensitive, case_preserve, short_case_preserve, directory,
+ newname, newname_last_component, is_short_name));
+
+ /*
+ * Check for special case with case preserving and not
+ * case sensitive, if directory and newname are identical,
+ * and the old last component differs from the original
+ * last component only by case, then we should allow
+ * the rename (user is trying to change the case of the
+ * filename).
+ */
+ if((case_sensitive == False) &&
+ (((case_preserve == True) &&
+ (is_short_name == False)) ||
+ ((short_case_preserve == True) &&
+ (is_short_name == True))) &&
+ strcsequal(directory, newname)) {
+ pstring newname_modified_last_component;
+
+ /*
+ * Get the last component of the modified name.
+ * Note that we guarantee that newname contains a '/'
+ * character above.
+ */
+ p = strrchr(newname,'/');
+ pstrcpy(newname_modified_last_component,p+1);
+
+ if(strcsequal(newname_modified_last_component,
+ newname_last_component) == False) {
+ /*
+ * Replace the modified last component with
+ * the original.
+ */
+ pstrcpy(p+1, newname_last_component);
+ }
+ }
+
+
+ resolve_wildcards(directory,newname);
+
+ /*
+ * The source object must exist.
+ */
+
+ if (!vfs_object_exist(conn, directory, &sbuf1)) {
+ DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
+ directory,newname));
+
+ if (errno == ENOTDIR || errno == EISDIR || errno == ENOENT) {
+ /*
+ * Must return different errors depending on whether the parent
+ * directory existed or not.
+ */
+
+ p = strrchr(directory, '/');
+ if (!p)
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ *p = '\0';
+ if (vfs_object_exist(conn, directory, NULL))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+ error = map_nt_error_from_unix(errno);
+ DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
+ get_nt_error_msg(error), directory,newname));
+
+ return error;
+ }
+
+ error = can_rename(directory,conn,&sbuf1);
+
+ if (!NT_STATUS_IS_OK(error)) {
+ DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
+ get_nt_error_msg(error), directory,newname));
+ return error;
+ }
+
+ pstrcpy(zdirectory, dos_to_unix_static(directory));
+ pstrcpy(znewname, dos_to_unix_static(newname));
+
+ /*
+ * If the src and dest names are identical - including case,
+ * don't do the rename, just return success.
+ */
+
+ if (strcsequal(zdirectory, znewname)) {
+ DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
+ return NT_STATUS_OK;
+ }
+
+ if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) {
+ DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
+ directory,newname));
+ return NT_STATUS_OBJECT_NAME_COLLISION;
+ }
+
+ if(conn->vfs_ops.rename(conn,zdirectory, znewname) == 0) {
+ DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
+ directory,newname));
+ return NT_STATUS_OK;
+ }
+
+ if (errno == ENOTDIR || errno == EISDIR)
+ error = NT_STATUS_OBJECT_NAME_COLLISION;
+ else
+ error = map_nt_error_from_unix(errno);
+
+ DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
+ get_nt_error_msg(error), directory,newname));
+
+ return error;
+ } else {
+
+ /*
+ * Wildcards - process each file that matches.
+ */
+ void *dirptr = NULL;
+ char *dname;
+ pstring destname;
+
+ if (check_name(directory,conn))
+ dirptr = OpenDir(conn, directory, True);
+
+ if (dirptr) {
+ error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ if (strequal(mask,"????????.???"))
+ pstrcpy(mask,"*");
+
+ while ((dname = ReadDirName(dirptr))) {
+ pstring fname;
+
+ pstrcpy(fname,dname);
+
+ if(!mask_match(fname, mask, case_sensitive))
+ continue;
+
+ error = NT_STATUS_ACCESS_DENIED;
+ slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
+ if (!vfs_object_exist(conn, fname, &sbuf1)) {
+ error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ DEBUG(6,("rename %s failed. Error %s\n", fname, get_nt_error_msg(error)));
+ continue;
+ }
+ error = can_rename(fname,conn,&sbuf1);
+ if (!NT_STATUS_IS_OK(error)) {
+ DEBUG(6,("rename %s failed. Error %s\n", fname, get_nt_error_msg(error)));
+ continue;
+ }
+ pstrcpy(destname,newname);
+
+ if (!resolve_wildcards(fname,destname)) {
+ DEBUG(6,("resolve_wildcards %s %s failed\n",
+ fname, destname));
+ continue;
+ }
+
+ if (!replace_if_exists &&
+ vfs_object_exist(conn,destname, NULL)) {
+ DEBUG(6,("file_exist %s\n", destname));
+ error = NT_STATUS_OBJECT_NAME_COLLISION;
+ continue;
+ }
+
+ if (!conn->vfs_ops.rename(conn,dos_to_unix_static(fname),
+ dos_to_unix_static(destname)))
+ count++;
+ DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
+ }
+ CloseDir(dirptr);
+ }
+ }
+
+ if (count == 0 && NT_STATUS_IS_OK(error)) {
+ error = map_nt_error_from_unix(errno);
+ }
+
+ return error;
+}
+
+/****************************************************************************
+ Reply to a mv.
+****************************************************************************/
+
+int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = 0;
+ pstring name;
+ pstring newname;
+ NTSTATUS status;
+ START_PROFILE(SMBmv);
+
+ pstrcpy(name,smb_buf(inbuf) + 1);
+ pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name));
+
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+
+ DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
+
+ status = rename_internals(conn, name, newname, False);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ERROR_NT(status);
+ }
+
+ /*
+ * Win2k needs a changenotify request response before it will
+ * update after a rename..
+ */
+ process_pending_change_notify_queue((time_t)0);
+ outsize = set_message(outbuf,0,0,True);
+
+ END_PROFILE(SMBmv);
+ return(outsize);
+}
+
+/*******************************************************************
+ Copy a file as part of a reply_copy.
+******************************************************************/
+
+static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
+ int count,BOOL target_is_directory, int *err_ret)
+{
+ int Access,action;
+ SMB_STRUCT_STAT src_sbuf, sbuf2;
+ 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,'/');
+ if (p)
+ p++;
+ else
+ p = src;
+ pstrcat(dest,"/");
+ pstrcat(dest,p);
+ }
+
+ if (!vfs_file_exist(conn,src,&src_sbuf))
+ return(False);
+
+ fsp1 = open_file_shared(conn,src,&src_sbuf,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)
+ return(False);
+
+ if (!target_is_directory && count)
+ ofun = FILE_EXISTS_OPEN;
+
+ if (vfs_stat(conn,dest,&sbuf2) == -1)
+ ZERO_STRUCTP(&sbuf2);
+
+ fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
+ ofun,src_sbuf.st_mode,0,&Access,&action);
+
+ if (!fsp2) {
+ close_file(fsp1,False);
+ return(False);
+ }
+
+ if ((ofun&3) == 1) {
+ if(conn->vfs_ops.lseek(fsp2,fsp2->fd,0,SEEK_END) == -1) {
+ DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
+ /*
+ * Stop the copy from occurring.
+ */
+ ret = -1;
+ src_sbuf.st_size = 0;
+ }
+ }
+
+ if (src_sbuf.st_size)
+ ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
+
+ close_file(fsp1,False);
+
+ /* Ensure the modtime is set correctly on the destination file. */
+ fsp2->pending_modtime = src_sbuf.st_mtime;
+
+ /*
+ * 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 == (SMB_OFF_T)src_sbuf.st_size);
+}
+
+/****************************************************************************
+ Reply to a file copy.
+****************************************************************************/
+
+int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int outsize = 0;
+ pstring name;
+ pstring directory;
+ pstring mask,newname;
+ char *p;
+ int count=0;
+ int error = ERRnoaccess;
+ int err = 0;
+ BOOL has_wild;
+ BOOL exists=False;
+ int tid2 = SVAL(inbuf,smb_vwv0);
+ int ofun = SVAL(inbuf,smb_vwv1);
+ int flags = SVAL(inbuf,smb_vwv2);
+ BOOL target_is_directory=False;
+ BOOL bad_path1 = False;
+ BOOL bad_path2 = False;
+ BOOL rc = True;
+ SMB_STRUCT_STAT sbuf1, sbuf2;
+ START_PROFILE(SMBcopy);
+
+ *directory = *mask = 0;
+
+ pstrcpy(name,smb_buf(inbuf));
+ pstrcpy(newname,smb_buf(inbuf) + 1 + strlen(name));
+
+ DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
+
+ if (tid2 != conn->cnum) {
+ /* can't currently handle inter share copies XXXX */
+ DEBUG(3,("Rejecting inter-share copy\n"));
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRSRV,ERRinvdevice);
+ }
+
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+
+ rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
+ unix_convert(newname,conn,0,&bad_path2,&sbuf2);
+
+ target_is_directory = VALID_STAT_OF_DIR(sbuf2);
+
+ if ((flags&1) && target_is_directory) {
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRDOS,ERRbadfile);
+ }
+
+ if ((flags&2) && !target_is_directory) {
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRDOS,ERRbadpath);
+ }
+
+ if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
+ /* wants a tree copy! XXXX */
+ DEBUG(3,("Rejecting tree copy\n"));
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ p = strrchr(name,'/');
+ if (!p) {
+ pstrcpy(directory,"./");
+ pstrcpy(mask,name);
+ } else {
+ *p = 0;
+ pstrcpy(directory,name);
+ pstrcpy(mask,p+1);
+ }
+
+ /*
+ * 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 && mangle_is_mangled(mask))
+ mangle_check_cache( mask, sizeof(pstring)-1 );
+
+ has_wild = ms_has_wild(mask);
+
+ if (!has_wild) {
+ pstrcat(directory,"/");
+ pstrcat(directory,mask);
+ if (resolve_wildcards(directory,newname) &&
+ copy_file(directory,newname,conn,ofun,
+ count,target_is_directory,&err)) count++;
+ if(!count && err) {
+ errno = err;
+ END_PROFILE(SMBcopy);
+ return(UNIXERROR(ERRHRD,ERRgeneral));
+ }
+ if (!count) exists = vfs_file_exist(conn,directory,NULL);
+ } else {
+ void *dirptr = NULL;
+ char *dname;
+ pstring destname;
+
+ if (check_name(directory,conn))
+ dirptr = OpenDir(conn, directory, True);
+
+ if (dirptr) {
+ error = ERRbadfile;
+
+ if (strequal(mask,"????????.???"))
+ pstrcpy(mask,"*");
+
+ while ((dname = ReadDirName(dirptr))) {
+ pstring fname;
+ pstrcpy(fname,dname);
+
+ if(!mask_match(fname, mask, case_sensitive))
+ continue;
+
+ error = ERRnoaccess;
+ slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
+ pstrcpy(destname,newname);
+ if (resolve_wildcards(fname,destname) &&
+ 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;
+ END_PROFILE(SMBcopy);
+ return(UNIXERROR(ERRHRD,ERRgeneral));
+ }
+
+ if (exists) {
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRDOS,error);
+ } else
+ {
+ if((errno == ENOENT) && (bad_path1 || bad_path2))
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ END_PROFILE(SMBcopy);
+ return(UNIXERROR(ERRDOS,error));
+ }
+ }
+
+ outsize = set_message(outbuf,1,0,True);
+ SSVAL(outbuf,smb_vwv0,count);
+
+ END_PROFILE(SMBcopy);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a setdir.
+****************************************************************************/
+
+int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ int snum;
+ int outsize = 0;
+ BOOL ok = False;
+ pstring newdir;
+ START_PROFILE(pathworks_setdir);
+
+ snum = SNUM(conn);
+ if (!CAN_SETDIR(snum)) {
+ END_PROFILE(pathworks_setdir);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ pstrcpy(newdir,smb_buf(inbuf) + 1);
+ strlower(newdir);
+
+ if (strlen(newdir) == 0) {
+ ok = True;
+ } else {
+ ok = vfs_directory_exist(conn,newdir,NULL);
+ if (ok) {
+ string_set(&conn->connectpath,newdir);
+ }
+ }
+
+ if (!ok) {
+ END_PROFILE(pathworks_setdir);
+ return ERROR_DOS(ERRDOS,ERRbadpath);
+ }
+
+ outsize = set_message(outbuf,0,0,True);
+ SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
+
+ DEBUG(3,("setdir %s\n", newdir));
+
+ END_PROFILE(pathworks_setdir);
+ return(outsize);
+}
+
+/****************************************************************************
+ Get a lock pid, dealing with large count requests.
+****************************************************************************/
+
+uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
+{
+ if(!large_file_format)
+ return SVAL(data,SMB_LPID_OFFSET(data_offset));
+ else
+ return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
+}
+
+/****************************************************************************
+ Get a lock count, dealing with large count requests.
+****************************************************************************/
+
+SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
+{
+ SMB_BIG_UINT count = 0;
+
+ if(!large_file_format) {
+ count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
+ } else {
+
+#if defined(HAVE_LONGLONG)
+ count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
+ ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
+#else /* HAVE_LONGLONG */
+
+ /*
+ * NT4.x seems to be broken in that it sends large file (64 bit)
+ * lockingX calls even if the CAP_LARGE_FILES was *not*
+ * negotiated. For boxes without large unsigned ints 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);
+ }
+
+ count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
+#endif /* HAVE_LONGLONG */
+ }
+
+ return count;
+}
+
+#if !defined(HAVE_LONGLONG)
+/****************************************************************************
+ Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
+****************************************************************************/
+
+static uint32 map_lock_offset(uint32 high, uint32 low)
+{
+ unsigned int i;
+ uint32 mask = 0;
+ uint32 highcopy = high;
+
+ /*
+ * Try and find out how many significant bits there are in high.
+ */
+
+ for(i = 0; highcopy; i++)
+ highcopy >>= 1;
+
+ /*
+ * We use 31 bits not 32 here as POSIX
+ * lock offsets may not be negative.
+ */
+
+ mask = (~0) << (31 - i);
+
+ if(low & mask)
+ return 0; /* Fail. */
+
+ high <<= (31 - i);
+
+ return (high|low);
+}
+#endif /* !defined(HAVE_LONGLONG) */
+
+/****************************************************************************
+ Get a lock offset, dealing with large offset requests.
+****************************************************************************/
+
+SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
+{
+ SMB_BIG_UINT offset = 0;
+
+ *err = False;
+
+ if(!large_file_format) {
+ offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
+ } else {
+
+#if defined(HAVE_LONGLONG)
+ offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
+ ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
+#else /* HAVE_LONGLONG */
+
+ /*
+ * NT4.x seems to be broken in that it sends large file (64 bit)
+ * lockingX calls even if the CAP_LARGE_FILES was *not*
+ * negotiated. For boxes without large unsigned ints 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_BIG_UINT)-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);
+ }
+
+ offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
+#endif /* HAVE_LONGLONG */
+ }
+
+ 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);
+ unsigned char locktype = CVAL(inbuf,smb_vwv3);
+ unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
+ uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
+ uint16 num_locks = SVAL(inbuf,smb_vwv7);
+ SMB_BIG_UINT count = 0, offset = 0;
+ uint16 lock_pid;
+ int32 lock_timeout = IVAL(inbuf,smb_vwv4);
+ int i;
+ char *data;
+ BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
+ BOOL err;
+ NTSTATUS status;
+
+ START_PROFILE(SMBlockingX);
+
+ CHECK_FSP(fsp,conn);
+
+ data = smb_buf(inbuf);
+
+ if (locktype & (LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_CHANGE_LOCKTYPE)) {
+ /* we don't support these - and CANCEL_LOCK makes w2k
+ and XP reboot so I don't really want to be
+ compatible! (tridge) */
+ return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ }
+
+ /* Check if this is an oplock break on a file
+ we have granted an oplock on.
+ */
+ if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
+ /* Client can insist on breaking to none. */
+ BOOL break_to_none = (oplocklevel == 0);
+
+ DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
+ (unsigned int)oplocklevel, fsp->fnum ));
+
+ /*
+ * Make sure we have granted an exclusive or batch oplock on this file.
+ */
+
+ 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 (%s).\n", fsp->fnum, fsp->fsp_name));
+
+ /* if this is a pure oplock break request then don't send a reply */
+ if (num_locks == 0 && num_ulocks == 0) {
+ END_PROFILE(SMBlockingX);
+ return -1;
+ } else {
+ END_PROFILE(SMBlockingX);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
+ }
+
+ if (remove_oplock(fsp, break_to_none) == 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 */
+ if (num_locks == 0 && num_ulocks == 0) {
+ /* Sanity check - ensure a pure oplock break is not a
+ chained request. */
+ if(CVAL(inbuf,smb_vwv0) != 0xff)
+ DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
+ (unsigned int)CVAL(inbuf,smb_vwv0) ));
+ END_PROFILE(SMBlockingX);
+ return -1;
+ }
+ }
+
+ /*
+ * We do this check *after* we have checked this is not a oplock break
+ * response message. JRA.
+ */
+
+ release_level_2_oplocks_on_change(fsp);
+
+ /* Data now points at the beginning of the list
+ of smb_unlkrng structs */
+ for(i = 0; i < (int)num_ulocks; i++) {
+ lock_pid = get_lock_pid( data, i, large_file_format);
+ count = get_lock_count( data, i, large_file_format);
+ offset = get_lock_offset( data, i, large_file_format, &err);
+
+ /*
+ * There is no error code marked "stupid client bug".... :-).
+ */
+ if(err) {
+ END_PROFILE(SMBlockingX);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
+ (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
+
+ status = do_unlock(fsp,conn,lock_pid,count,offset);
+ if (NT_STATUS_V(status)) {
+ END_PROFILE(SMBlockingX);
+ return ERROR_NT(status);
+ }
+ }
+
+ /* Setup the timeout in seconds. */
+
+ lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000);
+
+ /* Now do any requested locks */
+ data += ((large_file_format ? 20 : 10)*num_ulocks);
+
+ /* Data now points at the beginning of the list
+ of smb_lkrng structs */
+
+ for(i = 0; i < (int)num_locks; i++) {
+ lock_pid = get_lock_pid( data, i, large_file_format);
+ count = get_lock_count( data, i, large_file_format);
+ offset = get_lock_offset( data, i, large_file_format, &err);
+
+ /*
+ * There is no error code marked "stupid client bug".... :-).
+ */
+ if(err) {
+ END_PROFILE(SMBlockingX);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
+ (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name,
+ (int)lock_timeout ));
+
+ status = do_lock_spin(fsp,conn,lock_pid, count,offset,
+ ((locktype & 1) ? READ_LOCK : WRITE_LOCK));
+
+ if (NT_STATUS_V(status)) {
+ if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
+ /*
+ * A blocking lock was requested. Package up
+ * this smb into a queued request and push it
+ * onto the blocking lock queue.
+ */
+ if(push_blocking_lock_request(inbuf, length, lock_timeout, i, lock_pid, offset, count)) {
+ END_PROFILE(SMBlockingX);
+ return -1;
+ }
+ }
+ break;
+ }
+ }
+
+ /* If any of the above locks failed, then we must unlock
+ all of the previous locks (X/Open spec). */
+ if(i != num_locks && num_locks != 0) {
+ /*
+ * Ensure we don't do a remove on the lock that just failed,
+ * as under POSIX rules, if we have a lock already there, we
+ * will delete it (and we shouldn't) .....
+ */
+ for(i--; i >= 0; i--) {
+ lock_pid = get_lock_pid( data, i, large_file_format);
+ count = get_lock_count( data, i, large_file_format);
+ offset = get_lock_offset( data, i, large_file_format, &err);
+
+ /*
+ * There is no error code marked "stupid client bug".... :-).
+ */
+ if(err) {
+ END_PROFILE(SMBlockingX);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ do_unlock(fsp,conn,lock_pid,count,offset);
+ }
+ END_PROFILE(SMBlockingX);
+ return ERROR_NT(status);
+ }
+
+ set_message(outbuf,2,0,True);
+
+ DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
+ fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
+
+ END_PROFILE(SMBlockingX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
+}
+
+/* Back from the dead for OS/2..... JRA. */
+
+/****************************************************************************
+ Reply to a SMBreadbmpx (read block multiplex) request
+****************************************************************************/
+
+int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+{
+ ssize_t nread = -1;
+ ssize_t total_read;
+ char *data;
+ SMB_OFF_T startpos;
+ int outsize;
+ size_t maxcount;
+ int max_per_packet;
+ size_t tcount;
+ int pad;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBreadBmpx);
+
+ /* this function doesn't seem to work - disable by default */
+ if (!lp_readbmpx()) {
+ END_PROFILE(SMBreadBmpx);
+ return ERROR_DOS(ERRSRV,ERRuseSTD);
+ }
+
+ outsize = set_message(outbuf,8,0,True);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_READ(fsp);
+ CHECK_ERROR(fsp);
+
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
+ maxcount = SVAL(inbuf,smb_vwv3);
+
+ data = smb_buf(outbuf);
+ pad = ((long)data)%4;
+ if (pad)
+ pad = 4 - pad;
+ data += pad;
+
+ max_per_packet = bufsize-(outsize+pad);
+ tcount = maxcount;
+ total_read = 0;
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK, False)) {
+ END_PROFILE(SMBreadBmpx);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
+
+ do {
+ size_t N = MIN(max_per_packet,tcount-total_read);
+
+ nread = read_file(fsp,data,startpos,N);
+
+ if (nread <= 0)
+ nread = 0;
+
+ if (nread < (ssize_t)N)
+ tcount = total_read + nread;
+
+ set_message(outbuf,8,nread,False);
+ SIVAL(outbuf,smb_vwv0,startpos);
+ SSVAL(outbuf,smb_vwv2,tcount);
+ SSVAL(outbuf,smb_vwv6,nread);
+ SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
+
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("reply_readbmpx: send_smb failed.");
+
+ total_read += nread;
+ startpos += nread;
+ } while (total_read < (ssize_t)tcount);
+
+ END_PROFILE(SMBreadBmpx);
+ return(-1);
+}
+
+/****************************************************************************
+ Reply to a SMBsetattrE.
+****************************************************************************/
+
+int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+{
+ struct utimbuf unix_times;
+ int outsize = 0;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBsetattrE);
+
+ outsize = set_message(outbuf,0,0,True);
+
+ if(!fsp || (fsp->conn != conn)) {
+ END_PROFILE(SMBsetattrE);
+ return ERROR_DOS(ERRDOS,ERRbadfid);
+ }
+
+ /*
+ * Convert the DOS times into unix times. Ignore create
+ * time as UNIX can't set this.
+ */
+ unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
+ unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
+
+ /*
+ * Patch from Ray Frush <frush@engr.colostate.edu>
+ * Sometimes times are sent as zero - ignore them.
+ */
+
+ if ((unix_times.actime == 0) && (unix_times.modtime == 0)) {
+ /* Ignore request */
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
+ dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
+ }
+ END_PROFILE(SMBsetattrE);
+ return(outsize);
+ } else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) {
+ /* set modify time = to access time if modify time was 0 */
+ unix_times.modtime = unix_times.actime;
+ }
+
+ /* Set the date on this file */
+ if(file_utime(conn, fsp->fsp_name, &unix_times)) {
+ END_PROFILE(SMBsetattrE);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
+ fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
+
+ END_PROFILE(SMBsetattrE);
+ return(outsize);
+}
+
+
+/* Back from the dead for OS/2..... JRA. */
+
+/****************************************************************************
+ Reply to a SMBwritebmpx (write block multiplex primary) request.
+****************************************************************************/
+
+int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+{
+ size_t numtowrite;
+ ssize_t nwritten = -1;
+ int outsize = 0;
+ SMB_OFF_T startpos;
+ size_t tcount;
+ BOOL write_through;
+ int smb_doff;
+ char *data;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBwriteBmpx);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+ CHECK_ERROR(fsp);
+
+ tcount = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
+ write_through = BITSETW(inbuf+smb_vwv7,0);
+ numtowrite = SVAL(inbuf,smb_vwv10);
+ smb_doff = SVAL(inbuf,smb_vwv11);
+
+ data = smb_base(inbuf) + smb_doff;
+
+ /* If this fails we need to send an SMBwriteC response,
+ not an SMBwritebmpx - set this up now so we don't forget */
+ SCVAL(outbuf,smb_com,SMBwritec);
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
+ END_PROFILE(SMBwriteBmpx);
+ return(ERROR_DOS(ERRDOS,ERRlock));
+ }
+
+ nwritten = write_file(fsp,data,startpos,numtowrite);
+
+ if(lp_syncalways(SNUM(conn)) || write_through)
+ sync_file(conn,fsp);
+
+ if(nwritten < (ssize_t)numtowrite) {
+ END_PROFILE(SMBwriteBmpx);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
+
+ /* If the maximum to be written to this file
+ is greater than what we just wrote then set
+ up a secondary struct to be attached to this
+ fd, we will use this to cache error messages etc. */
+
+ if((ssize_t)tcount > nwritten) {
+ write_bmpx_struct *wbms;
+ if(fsp->wbmpx_ptr != NULL)
+ wbms = fsp->wbmpx_ptr; /* Use an existing struct */
+ else
+ wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
+
+ if(!wbms) {
+ DEBUG(0,("Out of memory in reply_readmpx\n"));
+ END_PROFILE(SMBwriteBmpx);
+ return(ERROR_DOS(ERRSRV,ERRnoresource));
+ }
+ wbms->wr_mode = write_through;
+ wbms->wr_discard = False; /* No errors yet */
+ wbms->wr_total_written = nwritten;
+ wbms->wr_errclass = 0;
+ wbms->wr_error = 0;
+ fsp->wbmpx_ptr = wbms;
+ }
+
+ /* We are returning successfully, set the message type back to
+ SMBwritebmpx */
+ SCVAL(outbuf,smb_com,SMBwriteBmpx);
+
+ outsize = set_message(outbuf,1,0,True);
+
+ SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
+
+ DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
+ fsp->fnum, (int)numtowrite, (int)nwritten ) );
+
+ if (write_through && tcount==nwritten) {
+ /* We need to send both a primary and a secondary response */
+ smb_setlen(outbuf,outsize - 4);
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("reply_writebmpx: send_smb failed.");
+
+ /* Now the secondary */
+ outsize = set_message(outbuf,1,0,True);
+ SCVAL(outbuf,smb_com,SMBwritec);
+ SSVAL(outbuf,smb_vwv0,nwritten);
+ }
+
+ END_PROFILE(SMBwriteBmpx);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a SMBwritebs (write block multiplex secondary) request.
+****************************************************************************/
+
+int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ size_t numtowrite;
+ ssize_t nwritten = -1;
+ int outsize = 0;
+ SMB_OFF_T startpos;
+ size_t tcount;
+ BOOL write_through;
+ int smb_doff;
+ char *data;
+ write_bmpx_struct *wbms;
+ BOOL send_response = False;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBwriteBs);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ tcount = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
+ numtowrite = SVAL(inbuf,smb_vwv6);
+ smb_doff = SVAL(inbuf,smb_vwv7);
+
+ data = smb_base(inbuf) + smb_doff;
+
+ /* We need to send an SMBwriteC response, not an SMBwritebs */
+ SCVAL(outbuf,smb_com,SMBwritec);
+
+ /* This fd should have an auxiliary struct attached,
+ check that it does */
+ wbms = fsp->wbmpx_ptr;
+ if(!wbms) {
+ END_PROFILE(SMBwriteBs);
+ return(-1);
+ }
+
+ /* If write through is set we can return errors, else we must cache them */
+ write_through = wbms->wr_mode;
+
+ /* Check for an earlier error */
+ if(wbms->wr_discard) {
+ END_PROFILE(SMBwriteBs);
+ return -1; /* Just discard the packet */
+ }
+
+ nwritten = write_file(fsp,data,startpos,numtowrite);
+
+ if(lp_syncalways(SNUM(conn)) || write_through)
+ sync_file(conn,fsp);
+
+ if (nwritten < (ssize_t)numtowrite) {
+ if(write_through) {
+ /* We are returning an error - we can delete the aux struct */
+ SAFE_FREE(wbms);
+ fsp->wbmpx_ptr = NULL;
+ END_PROFILE(SMBwriteBs);
+ return(ERROR_DOS(ERRHRD,ERRdiskfull));
+ }
+ END_PROFILE(SMBwriteBs);
+ return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
+ }
+
+ /* Increment the total written, if this matches tcount
+ we can discard the auxiliary struct (hurrah !) and return a writeC */
+ wbms->wr_total_written += nwritten;
+ if(wbms->wr_total_written >= tcount) {
+ if (write_through) {
+ outsize = set_message(outbuf,1,0,True);
+ SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
+ send_response = True;
+ }
+
+ SAFE_FREE(wbms);
+ fsp->wbmpx_ptr = NULL;
+ }
+
+ if(send_response) {
+ END_PROFILE(SMBwriteBs);
+ return(outsize);
+ }
+
+ END_PROFILE(SMBwriteBs);
+ return(-1);
+}
+
+/****************************************************************************
+ Reply to a SMBgetattrE.
+****************************************************************************/
+
+int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+{
+ SMB_STRUCT_STAT sbuf;
+ int outsize = 0;
+ int mode;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBgetattrE);
+
+ outsize = set_message(outbuf,11,0,True);
+
+ if(!fsp || (fsp->conn != conn)) {
+ END_PROFILE(SMBgetattrE);
+ return ERROR_DOS(ERRDOS,ERRbadfid);
+ }
+
+ /* Do an stat on this file */
+
+ if(fsp_stat(fsp, &sbuf)) {
+ END_PROFILE(SMBgetattrE);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ mode = dos_mode(conn,fsp->fsp_name,&sbuf);
+
+ /* Convert the times into dos times. Set create
+ * date to be last modify date as UNIX doesn't save
+ * this.
+ */
+
+ put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
+ put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
+ put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
+ if (mode & aDIR) {
+ SIVAL(outbuf,smb_vwv6,0);
+ SIVAL(outbuf,smb_vwv8,0);
+ } else {
+ SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
+ SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
+ }
+ SSVAL(outbuf,smb_vwv10, mode);
+
+ DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
+
+ END_PROFILE(SMBgetattrE);
+ return(outsize);
+}