diff options
author | Gerald Carter <jerry@samba.org> | 2004-07-22 13:09:38 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2004-07-22 13:09:38 +0000 |
commit | 3ec5aea9e2b9c1aae05c571f9d826816590dd9ae (patch) | |
tree | 50d458c987cd03ac01933e04e5f8cc2ce6d62e0b | |
parent | f36859b9e485d72d9a2ccc385a7b8f6bef67263b (diff) | |
download | samba-3ec5aea9e2b9c1aae05c571f9d826816590dd9ae.tar.gz |
r1564: checking in changes for 2.2.10samba-3.0.5samba-2.2.10
-rw-r--r-- | jerry2/WHATSNEW.txt | 1588 | ||||
-rw-r--r-- | jerry2/source/include/mangle.h | 14 | ||||
-rwxr-xr-x | jerry2/source/include/proto.h | 5092 | ||||
-rwxr-xr-x | jerry2/source/include/version.h | 1 | ||||
-rw-r--r-- | jerry2/source/smbd/filename.c | 506 | ||||
-rw-r--r-- | jerry2/source/smbd/mangle.c | 123 | ||||
-rw-r--r-- | jerry2/source/smbd/mangle_hash.c | 880 | ||||
-rw-r--r-- | jerry2/source/smbd/mangle_hash2.c | 661 | ||||
-rw-r--r-- | jerry2/source/smbd/reply.c | 5173 |
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); +} |