diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..c4be870 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..a8e6e6d --- /dev/null +++ b/README.txt @@ -0,0 +1,979 @@ +Thu Feb 11 15:10:26 EST 2010 +jcifs-1.3.14 + +A lock has been added to DcerpcHandle to ensure that the NT_CREATE_ANDX +and DCERPC bind are performed together as some pipes will return 'All +pipe instances are busy' errors if the client tries to open the same +pipe concurrently. + +JCIFS will no longer do a NetBIOS Node Status to determine the server +hostname as it seems some servers no longer respond to it which causes +a long delay on connect. + +Tue Jan 5 13:19:39 EDT 2010 +jcifs-1.3.13 + +Locking throughout the transport layer has been rewritten. This should +fix the long standing deadlock that has been reported in the past. Doubled +size of transient input buffer to accommodate SMB_COM_NEGOTIATE response +security blob (as observed with OSX Snow Leopard). A signing issue reading +data from an EMC server has been fixed. NTLMSSP logging has been improved. + +Fri Aug 14 13:45:57 EDT 2009 +jcifs-1.3.12 + +If NtlmPasswordAuthentication.ANONYMOUS was used, CAP_EXTENDED_SECURITY +could be incorrectly turned off resulting in a NullPointerException in +SmbComSessionSetupAndX.java. If a DC does not return any domain referrals, +a NullPointerException could occur. Both of these NPEs have been fixed. + +JCIFS could become confused when connecting to a server that also happened +to be a DFS root server. JCIFS will now create separate transports for +these two cases. + +Tue Jul 21 11:19:39 EDT 2009 +jcifs-1.3.11 + +The domain was incorrectly upper-cased when performing NTLMv2 +authentication. It so happened this was harmless to JCIFS but the nTOWFv2 +routine indicates that the domain is not supposed to be upper-cased +(unlike the username which is). + +Wed Jun 3 19:42:58 EDT 2009 +jcifs-1.3.10 + +When re-establishing a session an old UID could be set in the +SMB_COM_SESSION_SETUP_ANDX and cause a "The parameter is incorrect" +SmbException. This release explicitly sets the uid to 0 before initiating +a new session which fixes this error. + +Fri May 30 00:40:26 EDT 2009 +jcifs-1.3.9 + +* JCIFS will now iteratively try multiple replicated DFS targets if some + are not enabled (whereas previously JCIFS would quit if the first root + target was not accessible) +* Fixed "Invalid operation for ????? service" error when querying DFS +* Documented jcifs.smb.client.useExtendedSecurity and that it must be + set to false when using Samba 3.0.x +* All instances of UnicodeLittleUnmarked have been changed to UTF-16LE + (for platforms like Android) +* SmbFile.copyTo will now copy files larger than 4GB +* The API documentation has been heavily stripped of unnecessary classes + +Sat Mar 29 23:13:29 EDT 2009 +jcifs-1.3.8 + +RC4 has been implemented which eliminates the Java 1.5u7 +requirement. JCIFS 1.3 should now work with Java 1.4 (as well as 1.2 +did anyway). + +Thu Mar 12 14:22:47 EDT 2009 +jcifs-1.3.7 + +Share security with Samba 3.0 was broken. This has been fixed. + +Wed Mar 11 20:22:46 EDT 2009 +jcifs-1.3.5 + +Stand-alone DFS did not work with an IP address as opposed to a DNS or +NetBIOS hostname. This issue has been fixed. + +Sun Mar 9 11:46:15 EDT 2009 +jcifs-1.3.4 + +JCIFS 1.3.3 was accidentally compiled with Java 1.5. This release has +been compiled with Java 1.4. Note that NTLMv2 still requires Java 1.5 +update 7 for RC4. + +SMB parameter words were not decoded correctly (which were ultimately +related to the fact that the WordCount of the SMB_COM_NT_CREATE_ANDX +response is wrong because an extra 16 bytes for "offline files / +client side caching (CSC)". Ultimately this caused an error with the +SMB_COM_TREE_CONNECT_ANDX response of certain IBM clusters. This should +now be fixed. + +The status codes and text for NT_STATUS_INVALID_COMPUTER_NAME (0xC0000122) +and NT_STATUS_NO_TRUST_SAM_ACCOUNT (0xC000018B) have been added. + +Server capabilities in the SMB_COM_NEGOTIATE response were not being +read correctly. This issue has been fixed. + +The documentation regarding the return value of renameTo has been fixed. + +Sun Jan 25 14:31:31 EST 2009 +jcifs-1.3.3 + +If a jcifs.netbios.wins property is not supplied, the default +jcifs.resolveOrder is now LMHOSTS,DNS,BCAST whereas previously it was +LMHOSTS,BCAST,DNS. This is much more likely to eliminate annoying 6 +second timeouts waiting for BCAST queries to timeout. + +An "Invalid parameter" error would occur if the RC4 Cipher was not +available for NTLMv2. The logic has been adjusted so that the correct +error is thrown. Note that RC4 is only available in Java 1.5 update 7 and +later. Thus JCIFS 1.3 requires that version or NTLMv2 must be disabled. + +The NTLMSSP classes could try to load Cp850 which is not available in +the standard JRE. This has been fixed. + +Added setLength method to NdrBuffer class. + +Mon Dec 22 13:30:39 EST 2008 +jcifs-1.3.2 + +Querying Samba DFS links directly could fail due to a slight difference +in Samba v. Windows DFS referrals. This issue has been fixed. Querying +Samba DFS roots or paths under DFS links were not affected. + +Sat Nov 30 00:32:09 EST 2008 +jcifs-1.3.1 + +The NtlmPasswordAuthentication constructor has been modified to +canonicalize the username from DOMAIN\username or username@domain to +username and set the domain separately. + +The getNTLMv2Response method has been adjusted to permit the targetInfo +to be null. + +Minor changes to DFS have been applied that claim to prevent errors in +certain DFS scenarios. + +The NTLM HTTP Filter was broken in 1.3.0. Turning off useExtendedSecurity +reportedly fixes the issue. + +Note: The semantics of the fourth parameter of getNTLMv2Response has +changed. + +Sat Oct 25 17:45:51 EDT 2008 +jcifs-1.3.0 released + +NTLMv2 has been FULLY implemented and is now the default. Signatures +without and without various NTLMSSP flags (e.g. NTLMSSP_NEGOTIATE_NTLM2) +have been tested with Windows 2003 and Windows 2000. + +New default values are: + + jcifs.lmCompatibility = 3 + jcifs.smb.client.useExtendedSecurity = true + +Note: The NTLM HTTP Filter does not and can never support NTLMv2 as it +uses the main-in-the-middle technique which is specifically thwarted by +factoring the NTLMSSP TargetInformation block into the computed hashes. A +proper NTLMv2 HTTP authentication filter would require NETLOGON RPCs (or +possibly some kind of Kerberos digest authentication like Heimdal uses). + +Sun Oct 19 23:25:45 EDT 2008 +jcifs-1.2.25 + +The DcerpcHandle code to increase the stub size if alloc_hint was greater +than stub.length was not being engaged properly which would result in +an ArrayIndexOutOfBoundsException if the DCERPC response was larger than +0xffff. This has been fixed. + +Disabled decoding of NativeFileSystem field b/c it seems the iSeries +implementation sends this field in ASCII even though Unicode is +indicated. Fortunately the field is of no interest to anyone so we can +simply omit decoding it. + +Added check in copyTo to prevent a possible thread lockup when server +is disconnected during a copy. + +Force SMB_COM_TREE_CONNECT_ANDX service to always be what was passed to +the constructor (default is '?????'). IBM iSeries apparently does not +like explicitly specifying 'A:' which can occur on reconnect after +an soTimeout. + +Wed Jul 23 13:35:20 EDT 2008 +jcifs-1.2.24 + +The 2 line change that fixes stand-alond DFS was not in 1.2.23. Now it is. + +Sun Jul 20 22:28:40 EDT 2008 +jcifs-1.2.23 + +Recent domain-based DFS proper broke stand-alone DFS. This has been fixed. + +Wed Jun 25 20:26:33 EDT 2008 +jcifs-1.2.22 + +The SmbFileInputStream methods will now throw InterruptedIOExceptions +where apppropriate whereas previously they would throw SmbExceptions +with a root cause of TransportException with a root cause of +InterruptedException. + +If SmbSession.send() throw an exception it could leave the session in a +bad state which could cause "Invalid parameter" exceptions on subsequent +requests. + +An InterruptedException in jcifs.netbios.NameServiceClient was being +caught and ignored. It will now be re-thrown as an IOException so that all +threads used with/by JCIFS can be interrupted and caused to exit. Several +other similar (albeit less important) InterruptedExceptions were also +adjusted. + +A jcifs.smb.client.dfs.disabled property has been added to disable domain +based DFS so that the client does not try and fail to resolve paths as +domain paths in non-domain environments (e.g. on the local machine). + +The getSecurity and getShareSecurity methods will now return null if no +DACL is present on a file whereas previously it would retrun an empty +array. This allows the caller to distinguish between an empty DACL and +one that is simply empty. + +Wed May 28 22:46:56 EDT 2008 +jcifs-1.2.21 + +An NPE in jcifs.Config was accidentally introduced in 1.2.20. This has +been fixed. + +Tue May 27 16:06:13 EDT 2008 +jcifs-1.2.20 + +The Dfs cache was not thread safe. This has been fixed. The trusted +domains are now looked up with <1C> NetBIOS lookups to speed discovery. + +EMC could return "Access denied" for the SMB_COM_FIND_CLOSE2 on a +read-only share. A try catch was added to ignore errors for that request +since it otherwise has no logical importance. Examining a capture of XP +with EMC reveals that no SMB_COM_FIND_CLOSE2 is sent at all. + +The read logic could error on the special 0x80000005 status used +by named pipes to indicate more data should be read. This caused +SmbFile.getShareSecurity() to fail on large ACLs. This issue has been +fixed. The getShareSecurity() method would previously fail to resolve more +than about 110 SIDs in one call because of a limitation in JCIFS' ability +to emit multi-fragment request PDUs. The getShareSecurity() method has +been modified to process SIDs in chunks of 64 to work-around this issue. + +Sun Apr 6 19:46:47 EDT 2008 +jcifs-1.2.19 released + +This release adds proper support for domain based DFS roots that are not +hosted on domain controllers and eliminates the now-obsolete behavior of +building a merged list of shares across hosts. A new NetrDfsEnumEx RPC +is used to enumerate DFS roots when listing shares. The equals methods +for SmbFile and UniAddress could return true even though the files were +not equal. That issue has been fixed. Some SmbComOpenAndX parameters +were incorrectly swapped which would cause failure on Windows 98. + +Mon Feb 18 23:02:02 EST 2008 +jcifs-1.2.18 released + +No changes to the code. + +Removed docs/.todo.txt.swp that got caught in the tgz by accident. + +Wed Feb 6 00:05:42 EST 2008 +jcifs-1.2.18e released + +The SID.getServerSid() method could fail with NetApp servers due to a +"generic" mask values. The mask has been changed to 0x00000001 which +corresponds to an LsaOpenPolicy mask of POLICY_VIEW_LOCAL_INFORMATION. + +The LsaPolicyHandle class would not throw an error if the LsarOpenPolicy2 +call failed. This has been fixed. + +The SmbFile constructor could inappropriately URL decode the authority +component of SMB URLs. + +The NTLM HTTP Filter documentation has been updated. + +An Invalid state: 4 error has been fixed. + +A NetBIOS name service issue caused by Jetdirect printers has been fixed. + +An ArrayIndexOutOfBounds exception in the SmbException class has been +fixed. + +A NullPointerException in SmbSession.getChallengeForDomain() has been +fixed. + +A NullPointerException in NbtAddress related to hosts without adequate +localhost address configuration has been fixed. + +An ArrayIndexOutOfBounds exception could be thrown if a server requires +NTLMv2. This exception has been replaced with a more informative one. + +The SmbSessionSetup constructor will now compare the challenge and +encryptionKey using Arrays.equals instead of == to satisfy unforseen +use-cases that otherwise trigger an NT_STATUS_ACCESS_VIOLATION. + +If a share was unshared while JCIFS was in the middle of reading files +from it, the transport could enter an error state from which it could +not immediately recover if the share was restored. A small change to +SmbTransport.doRecv() fixes this problem. + +Tue Jun 26 16:11:31 EDT 2007 + +The DCERPC bind did not exactly mimic Windows which uses +SMB_COM_{WRITE,READ}_ANDX. We were using TransactNmPipe throughout which +could result in an 'Incorrect function' error when querying the LSA on +a NetApp server. JCIFS now implements the bind exactly like Windows to +help ensure compatibility with other servers. + +A minor performance flaw in the DCERPC code was found and fixed. + +Wed Jun 20 13:09:10 EDT 2007 +jcifs-1.2.14 released + +A new SID.getGroupMemberSids() method has been added that will return +the local group membership of SID (aka aliases). This release adds the +SAMR interface to the dcerpc code with the SamrEnumerateAliasesInDomain +RPC and numerous other calls to negotiate the necessary policy handles. + +Mon Jan 22 15:26:01 EST 2007 +jcifs-1.2.13 released + +A new SmbFile.getShareSecurity() method that uses a new +MsrpcShareGetInfo/ShareInfo502 RPC has been added. This will return the +ACL for a share as opposed to the ACL for the directory shared. See the +API documentation for details. Several DFS issues have been identified +and fixed. If JCIFS receives a NoRouteToHostException on port 445 it +will now try to fallback to port 139. This code has been tested fairly +well already. There have been no changes since b4. + +Mon Jan 15 15:47:47 EST 2007 +jcifs-1.2.13b4 released + +When trying to connect to port 445 some environments can generate a +NoRouteToHostException as opposed to a ConnectException even though +falling back to port 139 would have worked. The SmbTransport class has +been modifed to also catch the NoRouteToHostException and retry with +port 139. + +Mon Jan 8 02:26:56 EST 2007 +jcifs-1.2.13b3 released + +Two DFS bugs introduced after recent changes have been repaired. The +getDfsPath method would return a path with an extra slash (/) if the +directory referred to the DFS root. The listFiles methods could return +the directory itself as a child. Both issues have been fixed. + +Fri Jan 5 16:24:27 EST 2007 +jcifs-1.2.13b2 released + +The DcerpcHandle.sendrecv() code did not properly buffer fragmented +response PDUs. This resulted in an "invalid array conformance" exception +in the NDR routines. This error has been fixed. + +Thu Jan 4 18:12:34 EST 2007 +jcifs-1.2.13b1 released + +A new SmbFile.getShareSecurity() method that uses a new +MsrpcShareGetInfo/ShareInfo502 RPC has been added. See the API +documentation for details. Also, DFS issues have been identified and +fixed. + +Wed Dec 27 19:15:27 EST 2006 +jcifs-1.2.12 released + +Just made 1.2.12b2 final. + +Thu Dec 21 12:20:14 EST 2006 +jcifs-1.2.12b2 released / getSecurity Bugfix + +The NtTransQuerySecurityDesc request could specify a data buffer that +could be too small for the response. As a result the response was not +decoded properly and an error would occur. The response will now be +decoded properly if the buffer is too small and the buffer size has been +increased from 4096 to 32768. + +Thu Dec 14 21:01:46 EST 2006 +jcifs-1.2.12b released / DFS Bugfix and SID Adjustments Again + +The getSecurity() method did not work over DFS. A very small but +potentially significant change has been made to the DFS code. I do not +have a sophisticated DFS test environment so please pay special attention +to JCIFS with DFS and report any problems to the JCIFS mailing list. + +The toString() method of the SID class has been changed back to the +old behavior of returning only the numeric SID representation. This +was done not only for backward compatibility with previous versions of +JCIFS but because conceptually the textual representation of a SID is +not it's resolved account name. A new toDisplayString method has been +added to return the resolved Windows ACL editor text (as toString() did +in the 1.2.11 release). The toSidString() method has been removed. The +getDomainName() and getAccountName() methods have not changed. + +Sat Dec 9 01:09:43 EST 2006 +jcifs-1.2.11 released / SID Class Adjustments + +The 1.2.11 release is now final. No serious problems have been reported +with the new SID resolution code however some minor adjustments have been +made with respect to values returned when a SID has not been resolved +(e.g. the associated account was deleted). The SID class API documentation +has been updated accordingly. + +Wed Nov 29 11:34:01 EST 2006 +jcifs-1.2.11b released / SID Resolution + +This release significantly expands the SID and ACE classes by using the +new MSRPC infrastructure to resolve SIDs to their associated account +names. A new SmbFile.getSecurity() method has been added which if called +with a boolean value of true will resolve the SIDs returned within the +ACE[] array such that SID.toString()/getDomainName()/getAccountName() +will return text about the account associated with that SID suitable for +display to users (e.g. MYDOM\alice, SYSTEM, etc). Documentation for all +associated methods and classes has been added. + +Fri Nov 24 11:58:14 EST 2006 +jcifs-1.2.10 released / Minor Adjustments + +The 1.2.10 release is now final. A NetBIOS name service lookup bug has +been fixed in addition to severl other harmless adjustments. + +Tue Nov 14 12:32:23 EST 2006 +jcifs-1.2.10b released / MSRPC Support, Long Unicode Share Name + Enumeration and Critical Bugfixes + +This release contains the following new functionality and fixes: + + * Long Unicode Share Enumeration - The SmbFile.list* methods will now + try to use MSRPC to enumerate shares if the target is a server. If + the operation should fail for any reason, the client will fall + back to trying the older RAP method. This should permit enumerating + shares with names that use charsets other than the negotiated OEM + "ASCII" encoding, share names that are longer than 12 characters, + and arbirarily large lists of shares. + * MSRPC Support - MSRPC support has been integrated into JCIFS + directly. It should now be possible to add new RPCs (AT jobs, + SID/group name resolution, service management, regedit, etc) + relatively easily with little knowledge of MSRPC protocols. Look at + the jcifs/dcerpc/msrpc/MsrpcShareEnum.java class for an example and + ask the mailing list for further instructions. + * Apr 24 bugfix - A NullPointerException caused by an error in logic + has been fixed. + * May 10 bugfix - The client will now detect if the JRE supports Cp850 + and set the default jcifs.encoding to US-ASCII if it does not. This + will eliminate some NullPointerExceptions that were occuring as + a result. + * A small update about keep-alives has been added to the NTLM HTTP + Authentication document. + * Jun 21 bugfix - CLOSE-WAIT sockets left over by read errors have + been fixed. + * Jul 19 bugfix - Errors caused by using UnicodeLittle as + opposed to UnicodeLittleUnmarked have been fixed by ensuring + UnicodeLittleUnmarked is used throughout the codebase. + * Oct 3 bugfix - Invalid state errors from Transport classes have + been fixed. It should be safe to interrupt() JCIFS operations now. + * Oct 20 bugfix - Uncontrolled looping due to invalid Transport + logic has been fixed. + * Oct 25 bugfix - Logic has been added to make domain controller + lookups more robust. + * Oct 27 bugfix - Failure when using SmbFile.renameTo() with + jcifs.smb.client.ssnLimit=1 has been fixed. + * Oct 31 bugfix - Endless looping when all WINS servers in a list + are unavailable has been fixed. + +Note the openFlags used with SmbFile, SmbNamedPipe, and various streams +classes have been tweaked. They are now the following: + + Flags for SmbFile{In,Out}putStream are: + bits meaning + 0-15 open flags (e.g. O_RDWR) + 16-31 lower 16 bits of access mask shifted up 16 bits + + Flags for SmbNamedPipe are: + bits meaning + 0-7 open flags (e.g. O_RDWR) + 8-15 pipe type (e.g. PIPE_TYPE_CALL) + 16-31 lower 16 bits of access mask shifted up 16 bits + +Tue Apr 4 15:44:43 EDT 2006 +jcifs-1.2.9 released / Java 1.5 Compiler Issue + +The 1.2.8 release was compiled with Java 1.5.0_06. Under certain conditions +this could cause an error: java.lang.LinkageError: ... Unsupported +major.minor version 49.0. I have rebuilt the entire package using the +compiler I used previously (1.4.2_08). + +Fri Mar 24 23:14:35 EST 2006 +jcifs-1.2.8 released / Deadlock Fix, ACLs, DFS, NTLM HTTP Filter, and More + +There are several significant changes in this release. These include: + + o A deadlock could occur if the client tried to logoff and logon at + the same instant. This has been fixed. + o It was discovered that in at least some cases "preauthentication" + did not work properly. A very simple logical error would cause the + wrong signing digest to be installed. This has been fixed. + o The ACL patch has been integrated. The SmbFile.getSecurity() method + is now available. + o The jcifs.smb.client.responseTimeout and jcifs.smb.client.soTimeout + values have been increased from 10000ms and 15000ms to 30000ms and + 35000 respectively. Users with crawler type applications will almost + certainly want to reduce these values. + o Several logical errors in DFS referral handling have been fixed + (still no fix for the mystery preemtive behavior observed by Windows + clients). + o Documentation has been updated significantly. + +Fri Nov 18 17:08:56 EST 2005 +jcifs-1.2.7 released / Transport Error, Filter Changes, Integer Overflow, +User Contributed Patches, and More + +This release consists of the following changes: + + o Some debugging printlns left over from the last release have been + removed. + o Added setContentLength(0) to two other places for the NTLM HTTP + Filter. This is required for HTTP 1.0 clients (e.g. Google appliance + servers). + o The name service code will now properly resolve DNS names that begin + with digits. + o Several instances of possible integer overflow have been fixed. + o A patch for large read and write support has been added to the patches + directory. A patch for reading security descriptors has been added + to the patches directory. + o If a transport was in error due to a connection timeout it could + remain in the error state indefinitely. This issue has been fixed. + +Fri Oct 7 19:47:53 EDT 2005 +jcifs-1.2.6 released / Session Management and Filter Fix + +It was discovered that redundant sessions could be created. This problem +has been fixed but the fix is to not remove sessions from the list of +sessions for a transport which is somewhat of a waste of memory. This will +probably need to be revisited. It has been advised that the Filter call +setStatus() before setContentLength(0). This change has been implemented. + +Fri Sep 30 23:28:51 EDT 2005 +jcifs-1.2.5 released / Filter Exceptions, Stressing the Transport Layer, + and DFS Deadlock Fixed + +This release of the JCIFS client consists of the following changes. + +o It was discovered that a flaw in session expiration could cause sessions + to expire prematurely. This has been repaired. +o If the jcifs.netbios.hostname property is set, the client will + communicate using only NetBIOS over port 139. This is required for + environments that implement a policy restricting users to logging in from + certain computers. +o Under stress the client could incorrectly attempt to use the invalid + "NULL" transport. This has been fixed. +o Filter users could experience exceptions due to using the port 0 rather + than the default CIFS port. +o The client should now handle partial reads and socket exceptions more + gracefully. +o Under stress, the DFS referral query could cause the client to deadlock. + This has been fixed. + +Wed Sep 21 01:53:28 EDT 2005 +jcifs-1.2.4 released / Timeout Transport Exception, Bogus Signature Error, + and More + +A NetBIOS keep-alive message (received after ~10 minutes) would break +message processesing with a timedout waiting for response Exception. This +has been fixed. + +JCIFS would fail to validate responses with a status that is not zero. +Assuming we are calculating the verfication signature correctly I can only +assume the affected servers choose not to generate the correct signature +for error responses (perhaps for DOS reasons). Because JCIFS checked the +signature before the message status, an error response would fail with +"signature verification failure". This behavior has been changed so that +signatures are not verified if the status is non zero. + +It was discovered that the new transport (as of 1.2.x) could not cleanly +recover from temporary server failure (e.g. a restart). This has been +fixed. Methods will still throw Exceptions but moment the server comes back +online the client gracefully recover. + +Wed Aug 24 13:29:44 EDT 2005 +jcifs-1.2.3 released / Port 445 Fixed + +A mistake in the 1.2.2 release broke port 445 communication entirely. It +has been fixed. The exact error (with a sufficiently high loglevel) was +"Invalid payload size: 1". + +Sat Aug 20 00:26:11 EDT 2005 +jcifs-1.2.2 released / Exception "cannot assign requested address" Fixed, + Clusters, NetApp Filer, and More + +There have been a number of small fixes. These are: + +o The "cannot assign requested address" exception caused by trying to bind + the local address 127.0.0.1 has been fixed. +o In a cluster environment the NTLM HTTP Filter could fail with "account + currently disabled" or "Access denied" errors due to a deserialization + issue of "preauthentication" credentials stored in the HttpSession. The + initialization of default credentials has been changed however it is not + clear that the change will have any effect as I do not have a clustered + environment in which to test. +o The combination of plain text passwords and Unicode (largely specific to + Samba 3) has been fixed. +o A bogus debugging statement has been discovered and removed. Who left that + in there?! +o A Socket.shutdownOutput() call has been added to doDisconnect as it is + believed to reduce spurrious RST frames observed when abruptly shutting + down transports. These are believed to be harmless but they have been + associated with unsightly messages in Samba log files. +o The copyTo() method will now check to see if the source path is a child, + parent or equal to the destination path and if so throw a Source and + destination paths overlap exception. +o An additional debugging statement has been added to the NTLM HTTP Filter + domain controller interrogation code. +o The getDiskFreeSpace call could fail with NetApp Filer. It has been + repaired. + +Sun Jul 3 23:33:03 EDT 2005 +jcifs-1.2.1 released + +The SMB signing code was totally broken in the last release. It has been +reparied. The setAttributes method did not work on directories. This has +been fixed and the masks used to filter setAttributes/getAttributes have +been optimized to allow getting and setting all possible attributes based +on observed XP behavior. The getType() method would always return +TYPE_SHARE if the SmbFiles were obtained through the listFiles() method on +a workgroup or server URL. This issue has been fixed - getType() may now +return TYPE_PRINTER and TYPE_NAMEDPIPE. + +Sun May 22 18:22:32 EDT 2005 +jcifs-1.2.0 released + +This release is jcifs-1.1.11trans2 with the following modifications. + +Named pipes were broken when DCE transactions where added with 1.x. Call, +Transact, CreateFile, and DCE named pipe calls should now all work as +expected. The NetBIOS name resolution code will now use the last resource +record of a name query response if there are more than one. This appears to +be more correct in at least one instance (VMWare adapters on my workstation +at work are appearing first). + +Also note the trans releases below. + +Mon May 9 18:49:24 EDT 2005 +jcifs-1.1.11trans2 released + +Socket exception handling was non-existant and reads would actually not +read anything but 0's. These issues and other small issues have been fixed. + +Wed May 4 22:31:28 EDT 2005 +jcifs-1.1.11trans released + +This "transitional" release has all the 1.1.10 and 1.1.11 fixes as well as +more work on the transport layer. The last trans release had a silly mid +rollover bug. I have also emiminated a deadlock condition. These issues +have been fixed. Also the client will not properly try port 445 and +fallback to 139 as necessary. This *could* be stable enough that I might +try to promote this to 1.2.0. + +Thu Apr 7 23:02:48 EDT 2005 +jcifs-1.1.9trans released + +This is a 'transitional' or 'transport rewrite' release. It's stock 1.1.9 +but the transport layer has been refactored and reduced (actually totally +rewritten - SmbTransport.java is less than half the size of it's previous +version). It may still not be "correct" because I believe the high-load +concurrency issue may have to do with how sessions and trees are created. +That is another step that delves into how Principles will be handled so I +thought I would release this as is because it seems pretty stable so I +thought I would put it out there as a reference point. To give people an +insentive to actually use it I have changed the port to 445, applied the +share reconnect fix from Darren and the getDiskFreeSpace patch from Thomas. +Also if you really need the dial to go to 11, preliminary testing indicates +this transport is a few percent faster. + +Feb 28 03:09:31 EST 2005 +jcifs-1.1.9 released + +When multiplexing I/O, if socket buffers fill up such that packets can be +read in fragments (i.e. high load), it was possible for the 4 byte NetBIOS +header to be read incorrectly resulting in a bogus "unexpected EOF reading +netbios session header" exception. This problem has been fixed. Also, some +small javadoc updates have been applied. + +Thu Feb 10 22:29:12 EST 2005 +jcifs-1.1.8 released + +The blocked thread bug wasn't quite fixed in the last release. A lookup +exception (e.g. caused by an unresponsive domain controller) could leave a +thread blocked if many requests are being processed simultaneously. +Similarly the fix for the DC lookup code wasn't complete enough to handle +the unusual scenario where all DCs are unresponsive. Also, a malfomed +NetBIOS name query response could cause the name service thread to exit +incorrectly. These issues have been fixed. Finally, the URL handling of +smb://@/ (meaning "null" credentials) has been fixed. + +Sun Jan 16 17:30:17 EST 2005 +jcifs-1.1.7 released + +A bug introduced in a recent release that could cause threads to wait +indefinately has been fixed. After time many threads could be blocked +resulting in wasted resources. The DC lookup code has been modified to +gracefully handle WINS returning an empty list (e.g. due to temporary +network failure). A simple fix has been applied that premits SMB signatures +to work without specifying preauthentication credentials. The getAttributes +method will now return 31 bits of attributes whereas previously it would +mask off the lower 6 bits that JCIFS actually makes use of. A bug has been +fixed that under certain conditions prevented copyTo() from copying entire +shares. A try/catch block has been added to copyTo() to permit the copy to +continue if an error occurs. + +Mon Dec 27 17:53:42 EST 2004 +jcifs-1.1.6 released + +If a variable length 8 bit encodings such as Big5 is used the NTCreateAndX +command could fail. This bug has been fixed. If an +SmbFile{Input,Output}Stream was closed, a subsequent operation could cause +the file to be reopened. This behavior is now blocked such that operations +performed on a stream after it has been closed will generate an +IOException. Some transport layer synchronization has been adjusted. A +getPrincipal method has been added to SmbFile that will return the +NtlmPasswordAuthentication object used to create the file or pipe. The +documentation has been updated regarding transparent NTLM authentication in +Mozilla, the available method of SmbFileInputStream. + +Thu Dec 16 21:57:23 EST 2004 +jcifs-1.1.5 released + +It was discovered that an ArrayIndexOutOfBoundsException could occur if the +list of domain controllers returned by NbtAddress.getAllByName was shorter +than the list returned in the previous call (possibly because the WINS +query timed out and switched to an alternate WINS server). All NTLM HTTP +Authentication Filter users should upgrade to prevent this error. Also, the +value of jcifs.netbios.cachePolicy set by the NTLM HTTP Filter if it is +not specified has been doubled to 20 minutes. Finally, some log levels have +been increased such that running with jcifs.util.loglevel = 3 temporarily +is actually reasonable in a production environment (must use loglevel > 3 +to see individual SMB messages and loglevel > 5 to get hexdumps). + +Tue Dec 7 18:34:35 EST 2004 +jcifs-1.1.4 released + +Two bugs regarding the upcasing of domain and username fields with LMv2 +authentication (used with lmCompatibility = 3) have been fixed. +Additionally the firstCalledName/nextCalledName methods changed in 1.1.0 +have been changed back to the old behavior. The change was not warranted as +it did not emulate Windows behavior. + +Tue Nov 30 19:20:57 EST 2004 +jcifs-1.1.3 released + +A concurrency error was introduced with the getChallengeForDomain code used +by the NTLM HTTP Filter. This has been fixed. + +Sun Oct 31 00:58:04 EDT 2004 +jcifs-1.1.1 released + +The jcifs.smb.client.logonShare (and thus the JCIFSACL NTLM HTTP Filter +example) did not work. It would not restrict users to those found in the +ACL it would permit all authenticated users. This has been fixed. + +A bug was discovered and fixed in the named pipe code. If a specific +sequence of reads were performed the pipe could become corrupted. This fix +is necessary for multi-pdu DCE requests to work. + +A small bug in the new NbtAddress.getAllByName method has been repaired. It +will now broadcast for a name if a WINS address was not provided. + +jcifs-1.1.0 released + +The behavior of the firstCalledName/nextCalledName methods has been changed +to try SMBSERVER* first, then the NetBIOS hostname, then the 0x20 name from +a Node Status. It is pretty universal now that SMBSERVER* rules the day and +most servers return failure with the NetBIOS name so this behavior +eliminates a round trip during session establishment. + +The NbtAddress.getByName method has been implemented. This will return the +full list of RDATA for a name query response. Currently I believe only the +0x1C domain lookup actually returns multiple results. Note this is +different from getAllByAddress which does a node status. + +The socket code in SmbTransport has been modified to open the socket using +the transport thread. This permits the caller of the transport to call wait +for RESPONSE_TIMEOUT. This is great if your application has a tendency to +try to connect to hosts that do not exist. Normally that would take over a +minute to timeout. The single threaded SmbCrawler actually performs quite +well with the right properties set. + +An SmbSession.getChallengeForDomain() method has been added that returns an +NtlmChallenge object containing the byte[] challenge and UniAddress of the +domain controller from which it came. This method will rotate through a +list of at most jcifs.netbios.lookupRespLimit addresses and will only +return a challenge for a responsive server. Unresponsive servers will be +removed from the list until the jcifs.netbios.cachePolicy has expired. This +function is used by the NTLM HTTP Filter to locate suitable domain +controllers. + +Because of the above rotation there is a greater potential for transports +to remain open. Sessions with no activity (this is particularly true with +the NTLM HTTP Filter which really only touches the session once when the +user is authenticated) will be logged off after jcifs.smb.client.soTimeout. + +A read bug that only manafested itself with a certain EMC server has been +fixed. + +Mon Sep 6 20:44:14 EDT 2004 +jcifs-1.0.1 released + +The GUEST account fix broke guest access entirely for machines that +deliberately want it. So this is the original fix but with the test +condition corrected. + +Mon Sep 6 14:59:26 EDT 2004 +jcifs-1.0.0 released + +Other than minor changes in packaging this code is identical to 0.9.8 +released 3 days ago. From now one all development will continue in the 2.0 +(?) branch so that the 1.x series remains as stable as possible. + +Thu Sep 2 18:45:35 EDT 2004 +jcifs-0.9.8 released + +If the special "GUEST" account is not disabled (almost always is) it is +possible for a bogus username to be authenticated successfully. This +problem was only partially fixed previously. A clause was incorrectly added +that was intended to allow the username "guest" to be authenticated +successfully. It is now not possible for "guest" to be authenticated at +all. + +A log message has been added to the NtlmHttpFilter that will be logged +whenever an SmbAuthException is triggered and the jcifs.util.log.loglevel +is greater than 1. For example, to enable logging authentication failures +with the filter add the following to the filter section in your web.xml. + + + jcifs.util.loglevel + 2 + + +An ArrayIndexOutOfBoundsException that could occur if NTLMv2 is used but +lmCompatibility was not set to 3 accordingly has been fixed. + +Tue Aug 10 21:25:03 EDT 2004 +jcifs-0.9.7 released + +It was decided that the NTLM HTTP Filter should not set Connection: close +headers, a new SmbFile constructor has been added and a rogue debugging +statement has been removed. + +--8<-- + + JCIFS + The Java CIFS Client Library + http://jcifs.samba.org + +JCIFS is an Open Source client library that implements the CIFS/SMB +networking protocol in 100% Java. CIFS is the standard file sharing +protocol on the Microsoft Windows platform (e.g. Map Network Drive ...). +This client is used extensively in production on large Intranets. + +REQUIREMENTS: + +JCIFS jar file - http://jcifs.samba.org/src/ +Java 1.3 or above - http://java.sun.com/products/ + +INSTALLATION: + +Just add the jar file to you classpath as you would with any other jar. +More specifically: + +UNIX: + +Go to http://jcifs.samba.org and download the latest jar. If you download +the tgz archive you also get the source code and javadoc API documentation +(see critical properties discussed on the Overview page). Put it someplace +reasonable and extract it. For example: + + $ gunzip jcifs-1.0.0.tgz + $ tar -xvf jcifs-1.0.0.tar + +Add the jar to your classpath. There are two ways to do this. One is to +explicitly set it on the command line when you run your application like: + + $ java -cp myjars/jcifs-1.0.0.jar MyApplication + +but a more robust solution is to export it in your ~/.profile or +~/.bash_profile like: + + CLASSPATH=$CLASSPATH:/home/produser/myapp/myjars/jcifs-1.0.0.jar + export CLASSPATH + +WINDOWS: + +Go to http://jcifs.samba.org and download the latest jar. If you download +the zip archive you also get the source code and javadoc API documentation +(see critical properties discussed on the Overview page). Put it someplace +reasonable and extract it with something like Winzip. + +Add the jar to your classpath. There are two ways to do this. One is to +explicitly set it on the command line when you run your application like: + + C:\> java -cp myjars\jcifs-1.0.0.jar MyApplication + +but a more robust solution would be to change your system environment but +I'm not confident I can tell you accurately how to do that. + +It is also common that the CLASSPATH be specified in a shell script or +batch file. See the build.bat batch file that runs the Ant build tool as an +example. + +USING JCIFS: + +In general the public API is extremely simple. The jcifs.smb.SmbFile, +jcifs.smb.SmbFileInputStream, and jcifs.smb.SmbFileOutputStream classes are +analogous to the java.io.File, java.io.FileInputStream, and +java.io.FileOutputStream classes so if you know how to use those it should +be obvious how to use jCIFS provided you set any necessary properties(such +as WINS) and understand the smb:// URL syntax. + +Here's an example to retrieve a file: + + import jcifs.smb.*; + + jcifs.Config.setProperty( "jcifs.netbios.wins", "192.168.1.230" ); + SmbFileInputStream in = new SmbFileInputStream( + "smb://dom;user:pass@host/c/My Documents/report.txt" ); + byte[] b = new byte[8192]; + int n; + while(( n = in.read( b )) > 0 ) { + System.out.write( b, 0, n ); + } + +You can also write, rename, list contents of a directory, enumerate shares, +communicate with Win32 Named Pipe Servers, ...etc. + +The protocol handler for java.net.URL is also in place which means you +retrieve files using the URL class as you would with other protocols. For +example: + + jcifs.Config.registerSmbURLHandler(); //ensure protocol handler is loaded + URL url = new URL( "smb://dom;user:pass@host/share/dir/file.doc" ); + InputStream in = url.openStream(); + +This will also work with whatever else uses the URL class internally. For +example if you use RMI you can serve class files from an SMB share and use +the codebase property: + + -Djava.rmi.server.codebase=smb://mymachine/c/download/myapp.jar + +There are many example programs in the jcifs_1.0.0/examples/ directory. To +execute the Put example you might do: + + $ java -cp examples:jcifs-1.0.0.jar -Djcifs.properties=jcifs.prp \ + Put smb://dom;usr:pass@host/share/dir/file.doc + ########## + 582K transfered + +See the API documentation and supplimentary documents in the docs directory +or on the JCIFS website. + +BUILDING JCIFS FROM SOURCE: + +The Ant build tool is required to build JCIFS: + + http://jakarta.apache.org/ant/ + +After installing Ant just run 'ant' in the JCIFS directory. It should read +the build.xml and present a list of targets. To build a new jar after +modifying the source for example simply type 'ant jar'. + +ACKNOWLEDGEMENTS + +Special thanks to Eric Glass for work on NTLM, the NTLM HTTP Authentication +Filter, and RPCs. Thanks is also due to the Samba organization and +Christopher R. Hertel for starting the JCIFS project. Finally, thanks to +users who diagnose problems and provide the critical feedback and solutions +that make the Open Source model great. diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..f84afcc --- /dev/null +++ b/build.xml @@ -0,0 +1,238 @@ + + + + + + + +Available Build Targets: + +dependencies: Checks that all class dependencies are met. + compile: Builds the jCIFS classes. + jar: Packages the jCIFS classes into a .jar file. + docs: XSLT generated website pages + javadoc: Creates the Javadoc API documentation. + all: Performs all of the above. + + clean: Removes build artifacts. + allclean: Removes distribution and build artifacts. This + includes the .jar file, .class files, and + the Javadoc API documentation. + + jcifs: Builds the "all" target, followed by "clean". This + reproduces the distribution package contents. + distrib: Builds the "jcifs" target, and additionally + recreates the .zip and .tgz downloadable + distributions. + checksum: Creates MD5 checksums of the .zip and .tgz + distributions. + + usage: Displays this message. + + + + + + The Java Servlet API classes could not be found. These files can be + obtained from: + + http://java.sun.com/products/servlet/download.html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/api/allclasses-frame.html b/docs/api/allclasses-frame.html new file mode 100644 index 0000000..e10b686 --- /dev/null +++ b/docs/api/allclasses-frame.html @@ -0,0 +1,72 @@ + + + + + + +All Classes (JCIFS API) + + + + + + + + + + +All Classes +
+ + + + + +
ACE +
+Base64 +
+Config +
+DosFileFilter +
+HMACT64 +
+LogStream +
+NbtAddress +
+NtlmAuthenticator +
+NtlmContext +
+NtlmPasswordAuthentication +
+RC4 +
+SID +
+SmbAuthException +
+SmbException +
+SmbFile +
+SmbFileFilter +
+SmbFileInputStream +
+SmbFileOutputStream +
+SmbFilenameFilter +
+SmbNamedPipe +
+SmbRandomAccessFile +
+UniAddress +
+
+ + + diff --git a/docs/api/allclasses-noframe.html b/docs/api/allclasses-noframe.html new file mode 100644 index 0000000..504d621 --- /dev/null +++ b/docs/api/allclasses-noframe.html @@ -0,0 +1,72 @@ + + + + + + +All Classes (JCIFS API) + + + + + + + + + + +All Classes +
+ + + + + +
ACE +
+Base64 +
+Config +
+DosFileFilter +
+HMACT64 +
+LogStream +
+NbtAddress +
+NtlmAuthenticator +
+NtlmContext +
+NtlmPasswordAuthentication +
+RC4 +
+SID +
+SmbAuthException +
+SmbException +
+SmbFile +
+SmbFileFilter +
+SmbFileInputStream +
+SmbFileOutputStream +
+SmbFilenameFilter +
+SmbNamedPipe +
+SmbRandomAccessFile +
+UniAddress +
+
+ + + diff --git a/docs/api/constant-values.html b/docs/api/constant-values.html new file mode 100644 index 0000000..5cec436 --- /dev/null +++ b/docs/api/constant-values.html @@ -0,0 +1,1034 @@ + + + + + + +Constant Field Values (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Constant Field Values

+
+
+Contents + + + + + + +
+jcifs.netbios.*
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
jcifs.netbios.NbtAddress
+public static final intB_NODE0
+public static final intH_NODE3
+public static final intM_NODE2
+public static final java.lang.StringMASTER_BROWSER_NAME"\u0001\u0002__MSBROWSE__\u0002"
+public static final intP_NODE1
+public static final java.lang.StringSMBSERVER_NAME"*SMBSERVER "
+ +

+ +

+ + + + + +
+jcifs.smb.*
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
jcifs.smb.ACE
+public static final intDELETE65536
+public static final intFILE_APPEND_DATA4
+public static final intFILE_DELETE64
+public static final intFILE_EXECUTE32
+public static final intFILE_READ_ATTRIBUTES128
+public static final intFILE_READ_DATA1
+public static final intFILE_READ_EA8
+public static final intFILE_WRITE_ATTRIBUTES256
+public static final intFILE_WRITE_DATA2
+public static final intFILE_WRITE_EA16
+public static final intFLAGS_CONTAINER_INHERIT2
+public static final intFLAGS_INHERIT_ONLY8
+public static final intFLAGS_INHERITED16
+public static final intFLAGS_NO_PROPAGATE4
+public static final intFLAGS_OBJECT_INHERIT1
+public static final intGENERIC_ALL268435456
+public static final intGENERIC_EXECUTE536870912
+public static final intGENERIC_READ-2147483648
+public static final intGENERIC_WRITE1073741824
+public static final intREAD_CONTROL131072
+public static final intSYNCHRONIZE1048576
+public static final intWRITE_DAC262144
+public static final intWRITE_OWNER524288
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
jcifs.smb.SID
+public static final intSID_FLAG_RESOLVE_SIDS1
+public static final intSID_TYPE_ALIAS4
+public static final intSID_TYPE_DELETED6
+public static final intSID_TYPE_DOM_GRP2
+public static final intSID_TYPE_DOMAIN3
+public static final intSID_TYPE_INVALID7
+public static final intSID_TYPE_UNKNOWN8
+public static final intSID_TYPE_USE_NONE0
+public static final intSID_TYPE_USER1
+public static final intSID_TYPE_WKN_GRP5
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
jcifs.smb.SmbFile
+public static final intATTR_ARCHIVE32
+public static final intATTR_DIRECTORY16
+public static final intATTR_HIDDEN2
+public static final intATTR_READONLY1
+public static final intATTR_SYSTEM4
+public static final intATTR_VOLUME8
+public static final intCAP_DFS4096
+public static final intCAP_EXTENDED_SECURITY-2147483648
+public static final intCAP_LARGE_FILES8
+public static final intCAP_LEVEL_II_OPLOCKS128
+public static final intCAP_LOCK_AND_READ256
+public static final intCAP_MPX_MODE2
+public static final intCAP_NONE0
+public static final intCAP_NT_FIND512
+public static final intCAP_NT_SMBS16
+public static final intCAP_RAW_MODE1
+public static final intCAP_RPC_REMOTE_APIS32
+public static final intCAP_STATUS3264
+public static final intCAP_UNICODE4
+public static final intCMD_OFFSET4
+public static final intDEFAULT_MAX_MPX_COUNT10
+public static final intDEFAULT_PORT445
+public static final intDEFAULT_RCV_BUF_SIZE60416
+public static final intDEFAULT_RESPONSE_TIMEOUT30000
+public static final intDEFAULT_SND_BUF_SIZE16644
+public static final intDEFAULT_SO_TIMEOUT35000
+public static final intDEFAULT_SSN_LIMIT250
+public static final intDELETE65536
+public static final intERROR_CODE_OFFSET5
+public static final intFILE_APPEND_DATA4
+public static final intFILE_DELETE64
+public static final intFILE_EXECUTE32
+public static final intFILE_NO_SHARE0
+public static final intFILE_READ_ATTRIBUTES128
+public static final intFILE_READ_DATA1
+public static final intFILE_READ_EA8
+public static final intFILE_SHARE_DELETE4
+public static final intFILE_SHARE_READ1
+public static final intFILE_SHARE_WRITE2
+public static final intFILE_WRITE_ATTRIBUTES256
+public static final intFILE_WRITE_DATA2
+public static final intFILE_WRITE_EA16
+public static final intFLAGS_COPY_SOURCE_MODE_ASCII8
+public static final intFLAGS_COPY_TARGET_MODE_ASCII4
+public static final intFLAGS_LOCK_AND_READ_WRITE_AND_UNLOCK1
+public static final intFLAGS_NONE0
+public static final intFLAGS_NOTIFY_OF_MODIFY_ACTION64
+public static final intFLAGS_OFFSET9
+public static final intFLAGS_OPLOCK_REQUESTED_OR_GRANTED32
+public static final intFLAGS_PATH_NAMES_CANONICALIZED16
+public static final intFLAGS_PATH_NAMES_CASELESS8
+public static final intFLAGS_RECEIVE_BUFFER_POSTED2
+public static final intFLAGS_RESPONSE128
+public static final intFLAGS_TARGET_MUST_BE_DIRECTORY2
+public static final intFLAGS_TARGET_MUST_BE_FILE1
+public static final intFLAGS_TREE_COPY32
+public static final intFLAGS_VERIFY_ALL_WRITES16
+public static final intFLAGS2_EXTENDED_ATTRIBUTES2
+public static final intFLAGS2_EXTENDED_SECURITY_NEGOTIATION2048
+public static final intFLAGS2_LONG_FILENAMES1
+public static final intFLAGS2_NONE0
+public static final intFLAGS2_PERMIT_READ_IF_EXECUTE_PERM8192
+public static final intFLAGS2_RESOLVE_PATHS_IN_DFS4096
+public static final intFLAGS2_SECURITY_SIGNATURES4
+public static final intFLAGS2_STATUS3216384
+public static final intFLAGS2_UNICODE32768
+public static final intGENERIC_ALL268435456
+public static final intGENERIC_EXECUTE536870912
+public static final intGENERIC_READ-2147483648
+public static final intGENERIC_WRITE1073741824
+public static final intHEADER_LENGTH32
+public static final longMILLISECONDS_BETWEEN_1970_AND_160111644473600000l
+public static final intOPEN_FUNCTION_FAIL_IF_EXISTS0
+public static final intOPEN_FUNCTION_OVERWRITE_IF_EXISTS32
+public static final intREAD_CONTROL131072
+public static final intSECURITY_SHARE0
+public static final intSECURITY_USER1
+public static final intSIGNATURE_OFFSET14
+public static final intSYNCHRONIZE1048576
+public static final intTID_OFFSET24
+public static final intTYPE_COMM64
+public static final intTYPE_FILESYSTEM1
+public static final intTYPE_NAMED_PIPE16
+public static final intTYPE_PRINTER32
+public static final intTYPE_SERVER4
+public static final intTYPE_SHARE8
+public static final intTYPE_WORKGROUP2
+public static final java.lang.StringUNI_ENCODING"UTF-16LE"
+public static final intVC_NUMBER1
+public static final intWRITE_DAC262144
+public static final intWRITE_OWNER524288
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
jcifs.smb.SmbNamedPipe
+public static final intPIPE_TYPE_CALL256
+public static final intPIPE_TYPE_DCE_TRANSACT1536
+public static final intPIPE_TYPE_RDONLY1
+public static final intPIPE_TYPE_RDWR3
+public static final intPIPE_TYPE_TRANSACT512
+public static final intPIPE_TYPE_WRONLY2
+ +

+ +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/deprecated-list.html b/docs/api/deprecated-list.html new file mode 100644 index 0000000..932e86a --- /dev/null +++ b/docs/api/deprecated-list.html @@ -0,0 +1,148 @@ + + + + + + +Deprecated List (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Deprecated API

+
+ + + + + + + + +
+Deprecated Methods
jcifs.smb.SmbFile.toURL() +
+          Use getURL() instead 
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/help-doc.html b/docs/api/help-doc.html new file mode 100644 index 0000000..6143897 --- /dev/null +++ b/docs/api/help-doc.html @@ -0,0 +1,193 @@ + + + + + + +API Help (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+How This API Document Is Organized

+
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.

+Overview

+
+ +

+The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.

+

+Package

+
+ +

+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:

    +
  • Interfaces (italic)
  • Classes
  • Exceptions
  • Errors
+
+

+Class/Interface

+
+ +

+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
  • Class inheritance diagram
  • Direct Subclasses
  • All Known Subinterfaces
  • All Known Implementing Classes
  • Class/interface declaration
  • Class/interface description +

    +

  • Nested Class Summary
  • Field Summary
  • Constructor Summary
  • Method Summary +

    +

  • Field Detail
  • Constructor Detail
  • Method Detail
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+

+Use

+
+Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+

+Tree (Class Hierarchy)

+
+There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
    +
  • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
  • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+

+Deprecated API

+
+The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+

+Index

+
+The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+

+Prev/Next

+These links take you to the next or previous class, interface, package, or related page.

+Frames/No Frames

+These links show and hide the HTML frames. All pages are available with or without frames. +

+

+Serialized Form

+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description. +

+ + +This help file applies to API documentation generated using the standard doclet. + +
+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/index-all.html b/docs/api/index-all.html new file mode 100644 index 0000000..e2c1f8e --- /dev/null +++ b/docs/api/index-all.html @@ -0,0 +1,1364 @@ + + + + + + +Index (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A B C D E F G H I J L M N P R S T U W
+

+A

+
+
ACE - class jcifs.smb.ACE.
An Access Control Entry (ACE) is an element in a security descriptor + such as those associated with files and directories.
ACE() - +Constructor for class jcifs.smb.ACE +
  +
ANONYMOUS - +Static variable in class jcifs.smb.NtlmPasswordAuthentication +
  +
ATTR_ARCHIVE - +Static variable in class jcifs.smb.SmbFile +
A file with this bit on as returned by getAttributes() or set + with setAttributes() is an archived file +
ATTR_DIRECTORY - +Static variable in class jcifs.smb.SmbFile +
A file with this bit on as returned by getAttributes() is + a directory +
ATTR_HIDDEN - +Static variable in class jcifs.smb.SmbFile +
A file with this bit on as returned by getAttributes() or set + with setAttributes() will be hidden +
ATTR_READONLY - +Static variable in class jcifs.smb.SmbFile +
A file with this bit on as returned by getAttributes() or set + with setAttributes() will be read-only +
ATTR_SYSTEM - +Static variable in class jcifs.smb.SmbFile +
A file with this bit on as returned by getAttributes() or set + with setAttributes() will be a system file +
ATTR_VOLUME - +Static variable in class jcifs.smb.SmbFile +
A file with this bit on as returned by getAttributes() is + a volume +
accept(SmbFile) - +Method in class jcifs.smb.DosFileFilter +
  +
accept(SmbFile) - +Method in interface jcifs.smb.SmbFileFilter +
  +
accept(SmbFile, String) - +Method in interface jcifs.smb.SmbFilenameFilter +
  +
attributes - +Variable in class jcifs.smb.DosFileFilter +
  +
available() - +Method in class jcifs.smb.SmbFileInputStream +
This stream class is unbuffered. +
+
+

+B

+
+
B_NODE - +Static variable in class jcifs.netbios.NbtAddress +
A B node only broadcasts name queries. +
Base64 - class jcifs.util.Base64.
 
Base64() - +Constructor for class jcifs.util.Base64 +
  +
+
+

+C

+
+
CREATOR_OWNER - +Static variable in class jcifs.smb.SID +
  +
Config - class jcifs.Config.
This class uses a static Properties to act + as a cental repository for all jCIFS configuration properties.
canRead() - +Method in class jcifs.smb.SmbFile +
Tests to see if the file this SmbFile represents can be + read. +
canWrite() - +Method in class jcifs.smb.SmbFile +
Tests to see if the file this SmbFile represents + exists and is not marked read-only. +
clone() - +Method in class jcifs.util.HMACT64 +
  +
close() - +Method in class jcifs.smb.SmbFileInputStream +
Closes this input stream and releases any system resources associated with the stream. +
close() - +Method in class jcifs.smb.SmbFileOutputStream +
Closes this output stream and releases any system resources associated + with it. +
close() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
connect() - +Method in class jcifs.smb.SmbFile +
It is not necessary to call this method directly. +
copyTo(SmbFile) - +Method in class jcifs.smb.SmbFile +
This method will copy the file or directory represented by this + SmbFile and it's sub-contents to the location specified by the + dest parameter. +
createNewFile() - +Method in class jcifs.smb.SmbFile +
Create a new file but fail if it already exists. +
createTime() - +Method in class jcifs.smb.SmbFile +
Retrieve the time this SmbFile was created. +
+
+

+D

+
+
DEFAULT_OEM_ENCODING - +Static variable in class jcifs.Config +
  +
DELETE - +Static variable in class jcifs.smb.ACE +
  +
DosFileFilter - class jcifs.smb.DosFileFilter.
 
DosFileFilter(String, int) - +Constructor for class jcifs.smb.DosFileFilter +
  +
decode(String) - +Static method in class jcifs.util.Base64 +
Decodes the supplied Base-64 encoded string. +
delete() - +Method in class jcifs.smb.SmbFile +
This method will delete the file or directory specified by this + SmbFile. +
dfs - +Static variable in class jcifs.smb.SmbFile +
  +
+
+

+E

+
+
EVERYONE - +Static variable in class jcifs.smb.SID +
  +
encode(byte[]) - +Static method in class jcifs.util.Base64 +
Base-64 encodes the supplied block of data. +
engineDigest() - +Method in class jcifs.util.HMACT64 +
  +
engineDigest(byte[], int, int) - +Method in class jcifs.util.HMACT64 +
  +
engineGetDigestLength() - +Method in class jcifs.util.HMACT64 +
  +
engineReset() - +Method in class jcifs.util.HMACT64 +
  +
engineUpdate(byte) - +Method in class jcifs.util.HMACT64 +
  +
engineUpdate(byte[], int, int) - +Method in class jcifs.util.HMACT64 +
  +
equals(Object) - +Method in class jcifs.UniAddress +
Compare two addresses for equality. +
equals(Object) - +Method in class jcifs.netbios.NbtAddress +
Determines if this address is equal two another. +
equals(Object) - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Compares two NtlmPasswordAuthentication objects for + equality. +
equals(Object) - +Method in class jcifs.smb.SID +
  +
equals(Object) - +Method in class jcifs.smb.SmbFile +
Tests to see if two SmbFile objects are equal. +
exists() - +Method in class jcifs.smb.SmbFile +
Tests to see if the SMB resource exists. +
+
+

+F

+
+
FILE_APPEND_DATA - +Static variable in class jcifs.smb.ACE +
  +
FILE_DELETE - +Static variable in class jcifs.smb.ACE +
  +
FILE_EXECUTE - +Static variable in class jcifs.smb.ACE +
  +
FILE_NO_SHARE - +Static variable in class jcifs.smb.SmbFile +
When specified as the shareAccess constructor parameter, + other SMB clients (including other threads making calls into jCIFS) + will not be permitted to access the target file and will receive "The + file is being accessed by another process" message. +
FILE_READ_ATTRIBUTES - +Static variable in class jcifs.smb.ACE +
  +
FILE_READ_DATA - +Static variable in class jcifs.smb.ACE +
  +
FILE_READ_EA - +Static variable in class jcifs.smb.ACE +
  +
FILE_SHARE_DELETE - +Static variable in class jcifs.smb.SmbFile +
When specified as the shareAccess constructor parameter, + other SMB clients will be permitted to delete the target file while + this file is open. +
FILE_SHARE_READ - +Static variable in class jcifs.smb.SmbFile +
When specified as the shareAccess constructor parameter, + other SMB clients will be permitted to read from the target file while + this file is open. +
FILE_SHARE_WRITE - +Static variable in class jcifs.smb.SmbFile +
When specified as the shareAccess constructor parameter, + other SMB clients will be permitted to write to the target file while + this file is open. +
FILE_WRITE_ATTRIBUTES - +Static variable in class jcifs.smb.ACE +
  +
FILE_WRITE_DATA - +Static variable in class jcifs.smb.ACE +
  +
FILE_WRITE_EA - +Static variable in class jcifs.smb.ACE +
  +
FLAGS_CONTAINER_INHERIT - +Static variable in class jcifs.smb.ACE +
  +
FLAGS_INHERITED - +Static variable in class jcifs.smb.ACE +
  +
FLAGS_INHERIT_ONLY - +Static variable in class jcifs.smb.ACE +
  +
FLAGS_NO_PROPAGATE - +Static variable in class jcifs.smb.ACE +
  +
FLAGS_OBJECT_INHERIT - +Static variable in class jcifs.smb.ACE +
  +
firstCalledName() - +Method in class jcifs.UniAddress +
Guess first called name to try for session establishment. +
firstCalledName() - +Method in class jcifs.netbios.NbtAddress +
  +
+
+

+G

+
+
GENERIC_ALL - +Static variable in class jcifs.smb.ACE +
  +
GENERIC_EXECUTE - +Static variable in class jcifs.smb.ACE +
  +
GENERIC_READ - +Static variable in class jcifs.smb.ACE +
  +
GENERIC_WRITE - +Static variable in class jcifs.smb.ACE +
  +
get(String) - +Static method in class jcifs.Config +
Retrieve a property as an Object. +
getAccessMask() - +Method in class jcifs.smb.ACE +
Returns the access mask accociated with this ACE. +
getAccountName() - +Method in class jcifs.smb.SID +
Return the sAMAccountName of this SID unless it could not + be resolved in which case the numeric RID is returned. +
getAddress() - +Method in class jcifs.UniAddress +
Return the underlying NbtAddress or InetAddress. +
getAddress() - +Method in class jcifs.netbios.NbtAddress +
Returns the raw IP address of this NbtAddress. +
getAllByAddress(String) - +Static method in class jcifs.netbios.NbtAddress +
Retrieve all addresses of a host by it's address. +
getAllByAddress(String, int, String) - +Static method in class jcifs.netbios.NbtAddress +
Retrieve all addresses of a host by it's address. +
getAllByAddress(NbtAddress) - +Static method in class jcifs.netbios.NbtAddress +
Retrieve all addresses of a host by it's address. +
getAllByName(String, boolean) - +Static method in class jcifs.UniAddress +
  +
getAllByName(String, int, String, InetAddress) - +Static method in class jcifs.netbios.NbtAddress +
  +
getAnsiHash(byte[]) - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Computes the 24 byte ANSI password hash given the 8 byte server challenge. +
getApplyToText() - +Method in class jcifs.smb.ACE +
Returns the 'Apply To' text for inheritance of ACEs on + directories such as 'This folder, subfolder and files'. +
getAttributes() - +Method in class jcifs.smb.SmbFile +
Return the attributes of this file. +
getBoolean(String, boolean) - +Static method in class jcifs.Config +
Retrieve a boolean value. +
getByName(String) - +Static method in class jcifs.UniAddress +
Determines the address of a host given it's host name. +
getByName(String, boolean) - +Static method in class jcifs.UniAddress +
Lookup hostname and return it's UniAddress. +
getByName(String) - +Static method in class jcifs.netbios.NbtAddress +
Determines the address of a host given it's host name. +
getByName(String, int, String) - +Static method in class jcifs.netbios.NbtAddress +
Determines the address of a host given it's host name. +
getByName(String, int, String, InetAddress) - +Static method in class jcifs.netbios.NbtAddress +
  +
getCanonicalPath() - +Method in class jcifs.smb.SmbFile +
Returns the full URL of this SMB resource with '.' and '..' components + factored out. +
getContentLength() - +Method in class jcifs.smb.SmbFile +
This URLConnection method just returns the result of length(). +
getDate() - +Method in class jcifs.smb.SmbFile +
This URLConnection method just returns the result of lastModified. +
getDfsPath() - +Method in class jcifs.smb.SmbFile +
If the path of this SmbFile falls within a DFS volume, + this method will return the referral path to which it maps. +
getDiskFreeSpace() - +Method in class jcifs.smb.SmbFile +
This method returns the free disk space in bytes of the drive this share + represents or the drive on which the directory or file resides. +
getDomain() - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Returns the domain. +
getDomainName() - +Method in class jcifs.smb.SID +
Return the domain name of this SID unless it could not be + resolved in which case the numeric representation is returned. +
getDomainSid() - +Method in class jcifs.smb.SID +
  +
getFilePointer() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
getFlags() - +Method in class jcifs.smb.ACE +
Returns the flags for this ACE. +
getGroupMemberSids(String, NtlmPasswordAuthentication, int) - +Method in class jcifs.smb.SID +
  +
getHostAddress() - +Method in class jcifs.UniAddress +
Return the IP address as text such as "192.168.1.15". +
getHostAddress() - +Method in class jcifs.netbios.NbtAddress +
Returns this IP adress as a String in the form "%d.%d.%d.%d". +
getHostName() - +Method in class jcifs.UniAddress +
Return the hostname of this address such as "MYCOMPUTER". +
getHostName() - +Method in class jcifs.netbios.NbtAddress +
The hostname of this address. +
getInetAddress(String, InetAddress) - +Static method in class jcifs.Config +
Retrieve an InetAddress. +
getInetAddress() - +Method in class jcifs.netbios.NbtAddress +
To convert this address to an InetAddress. +
getInetAddressArray(String, String, InetAddress[]) - +Static method in class jcifs.Config +
Retrieve an array of InetAddress created from a property + value containting a delim separated list of hostnames and/or + ipaddresses. +
getInputStream() - +Method in class jcifs.smb.SmbFile +
This URLConnection method just returns a new SmbFileInputStream created with this file. +
getInstance() - +Static method in class jcifs.util.LogStream +
  +
getInt(String, int) - +Static method in class jcifs.Config +
Retrieve an int. +
getInt(String) - +Static method in class jcifs.Config +
Retrieve an int. +
getLMv2Response(String, String, String, byte[], byte[]) - +Static method in class jcifs.smb.NtlmPasswordAuthentication +
Creates the LMv2 response for the supplied information. +
getLMv2Response(byte[], byte[], byte[]) - +Static method in class jcifs.smb.NtlmPasswordAuthentication +
  +
getLastModified() - +Method in class jcifs.smb.SmbFile +
This URLConnection method just returns the result of lastModified. +
getLocalHost() - +Static method in class jcifs.Config +
  +
getLocalHost() - +Static method in class jcifs.netbios.NbtAddress +
Retrieves the local host address. +
getLocalName() - +Static method in class jcifs.netbios.NbtAddress +
  +
getLong(String, long) - +Static method in class jcifs.Config +
Retrieve a long. +
getMacAddress() - +Method in class jcifs.netbios.NbtAddress +
Retrieves the MAC address of the remote network interface. +
getNTLM2Response(byte[], byte[], byte[]) - +Static method in class jcifs.smb.NtlmPasswordAuthentication +
  +
getNTLMResponse(String, byte[]) - +Static method in class jcifs.smb.NtlmPasswordAuthentication +
Generate the Unicode MD4 hash for the password associated with these credentials. +
getNTLMv2Response(byte[], byte[], byte[], long, byte[]) - +Static method in class jcifs.smb.NtlmPasswordAuthentication +
  +
getName() - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Return the domain and username in the format: + domain\\username. +
getName() - +Method in class jcifs.smb.SmbFile +
Returns the last component of the target URL. +
getNameType() - +Method in class jcifs.netbios.NbtAddress +
Returned the hex code associated with this name(e.g. +
getNamedPipeInputStream() - +Method in class jcifs.smb.SmbNamedPipe +
Return the InputStream used to read information + from this pipe instance. +
getNamedPipeOutputStream() - +Method in class jcifs.smb.SmbNamedPipe +
Return the OutputStream used to write + information to this pipe instance. +
getNetbiosName() - +Method in class jcifs.smb.NtlmContext +
  +
getNodeType() - +Method in class jcifs.netbios.NbtAddress +
Checks the node type of this address. +
getNtStatus() - +Method in class jcifs.smb.SmbException +
  +
getNtlmPasswordAuthentication() - +Method in class jcifs.smb.NtlmAuthenticator +
An application extending this class must provide an implementation for this method that returns new user credentials try try when accessing SMB resources described by the getRequestingURL and getRequestingException methods. +
getOutputStream() - +Method in class jcifs.smb.SmbFile +
This URLConnection method just returns a new SmbFileOutputStream created with this file. +
getParent() - +Method in class jcifs.smb.SmbFile +
Everything but the last component of the URL representing this SMB + resource is effectivly it's parent. +
getPassword() - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Returns the password in plain text or null if the raw password + hashes were used to construct this NtlmPasswordAuthentication + object which will be the case when NTLM HTTP Authentication is + used. +
getPath() - +Method in class jcifs.smb.SmbFile +
Returns the full uncanonicalized URL of this SMB resource. +
getPreNTLMResponse(String, byte[]) - +Static method in class jcifs.smb.NtlmPasswordAuthentication +
Generate the ANSI DES hash for the password associated with these credentials. +
getPrincipal() - +Method in class jcifs.smb.SmbFile +
Returns the NtlmPasswordAuthentication object used as + credentials with this file or pipe. +
getProperty(String, String) - +Static method in class jcifs.Config +
Retrieve a String. +
getProperty(String) - +Static method in class jcifs.Config +
Retrieve a String. +
getRequestingException() - +Method in class jcifs.smb.NtlmAuthenticator +
  +
getRequestingURL() - +Method in class jcifs.smb.NtlmAuthenticator +
  +
getRid() - +Method in class jcifs.smb.SID +
  +
getRootCause() - +Method in class jcifs.smb.SmbException +
  +
getSID() - +Method in class jcifs.smb.ACE +
Return the SID associated with this ACE. +
getSecurity(boolean) - +Method in class jcifs.smb.SmbFile +
Return an array of Access Control Entry (ACE) objects representing + the security descriptor associated with this file or directory. +
getSecurity() - +Method in class jcifs.smb.SmbFile +
Return an array of Access Control Entry (ACE) objects representing + the security descriptor associated with this file or directory. +
getServer() - +Method in class jcifs.smb.SmbFile +
Retrieve the hostname of the server for this SMB resource. +
getServerChallenge() - +Method in class jcifs.smb.NtlmContext +
  +
getServerSid(String, NtlmPasswordAuthentication) - +Static method in class jcifs.smb.SID +
  +
getShare() - +Method in class jcifs.smb.SmbFile +
Retrieves the share associated with this SMB resource. +
getShareSecurity(boolean) - +Method in class jcifs.smb.SmbFile +
Return an array of Access Control Entry (ACE) objects representing + the share permissions on the share exporting this file or directory. +
getSigningKey() - +Method in class jcifs.smb.NtlmContext +
  +
getSigningKey(byte[]) - +Method in class jcifs.smb.NtlmPasswordAuthentication +
  +
getType() - +Method in class jcifs.smb.SID +
Returns the type of this SID indicating the state or type of account. +
getType() - +Method in class jcifs.smb.SmbFile +
Returns type of of object this SmbFile represents. +
getTypeText() - +Method in class jcifs.smb.SID +
Return text represeting the SID type suitable for display to + users. +
getUncPath() - +Method in class jcifs.smb.SmbFile +
Retuns the Windows UNC style path with backslashs intead of forward slashes. +
getUnicodeHash(byte[]) - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Computes the 24 byte Unicode password hash given the 8 byte server challenge. +
getUserSessionKey(byte[]) - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Returns the effective user session key. +
getUsername() - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Returns the username. +
getWINSAddress() - +Static method in class jcifs.netbios.NbtAddress +
  +
+
+

+H

+
+
HMACT64 - class jcifs.util.HMACT64.
This is an implementation of the HMACT64 keyed hashing algorithm.
HMACT64(byte[]) - +Constructor for class jcifs.util.HMACT64 +
Creates an HMACT64 instance which uses the given secret key material. +
H_NODE - +Static variable in class jcifs.netbios.NbtAddress +
A Hybrid node tries to resolve a name using the nameserver first. +
hashCode() - +Method in class jcifs.UniAddress +
Return the IP address of this address as a 32 bit integer. +
hashCode() - +Method in class jcifs.netbios.NbtAddress +
Returns a hashcode for this IP address. +
hashCode() - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Return the upcased username hash code. +
hashCode() - +Method in class jcifs.smb.SID +
  +
hashCode() - +Method in class jcifs.smb.SmbFile +
Computes a hashCode for this file based on the URL string and IP + address if the server. +
+
+

+I

+
+
init(byte[], int, int) - +Method in class jcifs.util.RC4 +
  +
initSecContext(byte[], int, int) - +Method in class jcifs.smb.NtlmContext +
  +
isActive() - +Method in class jcifs.netbios.NbtAddress +
Determines if this address is active. +
isAllow() - +Method in class jcifs.smb.ACE +
Returns true if this ACE is an allow ACE and false if it is a deny ACE. +
isBeingDeleted() - +Method in class jcifs.netbios.NbtAddress +
Determines if this address in the process of being deleted. +
isDirectory() - +Method in class jcifs.smb.SmbFile +
Tests to see if the file this SmbFile represents is a directory. +
isEstablished() - +Method in class jcifs.smb.NtlmContext +
  +
isFile() - +Method in class jcifs.smb.SmbFile +
Tests to see if the file this SmbFile represents is not a directory. +
isGroupAddress() - +Method in class jcifs.netbios.NbtAddress +
Determines if the address is a group address. +
isHidden() - +Method in class jcifs.smb.SmbFile +
Tests to see if the file this SmbFile represents is marked as + hidden. +
isInConflict() - +Method in class jcifs.netbios.NbtAddress +
Determines if this address in conflict with another address. +
isInherited() - +Method in class jcifs.smb.ACE +
Returns true if this ACE is an inherited ACE and false if it is a direct ACE. +
isOpen() - +Method in class jcifs.smb.SmbFileOutputStream +
  +
isPermanent() - +Method in class jcifs.netbios.NbtAddress +
Determines if this address is set to be permanent. +
isWINS(InetAddress) - +Static method in class jcifs.netbios.NbtAddress +
  +
+
+

+J

+
+
jcifs - package jcifs
 
jcifs.netbios - package jcifs.netbios
 
jcifs.smb - package jcifs.smb
 
jcifs.util - package jcifs.util
 
+
+

+L

+
+
LogStream - class jcifs.util.LogStream.
0 - nothing +1 - critical [default] +2 - basic info can be logged under load +3 - almost everything +N - debugging
LogStream(PrintStream) - +Constructor for class jcifs.util.LogStream +
  +
lastModified() - +Method in class jcifs.smb.SmbFile +
Retrieve the last time the file represented by this + SmbFile was modified. +
length() - +Method in class jcifs.smb.SmbFile +
Returns the length of this SmbFile in bytes. +
length() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
level - +Static variable in class jcifs.util.LogStream +
  +
list(PrintStream) - +Static method in class jcifs.Config +
List the properties in the Code. +
list() - +Method in class jcifs.smb.SmbFile +
List the contents of this SMB resource. +
list(SmbFilenameFilter) - +Method in class jcifs.smb.SmbFile +
List the contents of this SMB resource. +
listFiles() - +Method in class jcifs.smb.SmbFile +
List the contents of this SMB resource as an array of + SmbFile objects. +
listFiles(String) - +Method in class jcifs.smb.SmbFile +
The CIFS protocol provides for DOS "wildcards" to be used as + a performance enhancement. +
listFiles(SmbFilenameFilter) - +Method in class jcifs.smb.SmbFile +
List the contents of this SMB resource. +
listFiles(SmbFileFilter) - +Method in class jcifs.smb.SmbFile +
List the contents of this SMB resource. +
load(InputStream) - +Static method in class jcifs.Config +
Load the Config with properties from the stream + in from a Properties file. +
+
+

+M

+
+
MASTER_BROWSER_NAME - +Static variable in class jcifs.netbios.NbtAddress +
This is a special name for querying the master browser that serves the + list of hosts found in "Network Neighborhood". +
M_NODE - +Static variable in class jcifs.netbios.NbtAddress +
Try Broadcast queries first, then try to resolve the name using the + nameserver. +
mkdir() - +Method in class jcifs.smb.SmbFile +
Creates a directory with the path specified by this + SmbFile. +
mkdirs() - +Method in class jcifs.smb.SmbFile +
Creates a directory with the path specified by this SmbFile + and any parent directories that do not exist. +
+
+

+N

+
+
NbtAddress - class jcifs.netbios.NbtAddress.
This class represents a NetBIOS over TCP/IP address.
NtlmAuthenticator - class jcifs.smb.NtlmAuthenticator.
This class can be extended by applications that wish to trap authentication related exceptions and automatically retry the exceptional operation with different credentials.
NtlmAuthenticator() - +Constructor for class jcifs.smb.NtlmAuthenticator +
  +
NtlmContext - class jcifs.smb.NtlmContext.
For initiating NTLM authentication (including NTLMv2).
NtlmContext(NtlmPasswordAuthentication, boolean) - +Constructor for class jcifs.smb.NtlmContext +
  +
NtlmPasswordAuthentication - class jcifs.smb.NtlmPasswordAuthentication.
This class stores and encrypts NTLM user credentials.
NtlmPasswordAuthentication(String) - +Constructor for class jcifs.smb.NtlmPasswordAuthentication +
Create an NtlmPasswordAuthentication object from the userinfo + component of an SMB URL like "domain;user:pass". +
NtlmPasswordAuthentication(String, String, String) - +Constructor for class jcifs.smb.NtlmPasswordAuthentication +
Create an NtlmPasswordAuthentication object from a + domain, username, and password. +
NtlmPasswordAuthentication(String, String, byte[], byte[], byte[]) - +Constructor for class jcifs.smb.NtlmPasswordAuthentication +
Create an NtlmPasswordAuthentication object with raw password + hashes. +
nTOWFv1(String) - +Static method in class jcifs.smb.NtlmPasswordAuthentication +
  +
nTOWFv2(String, String, String) - +Static method in class jcifs.smb.NtlmPasswordAuthentication +
  +
nextCalledName() - +Method in class jcifs.UniAddress +
Guess next called name to try for session establishment. +
nextCalledName() - +Method in class jcifs.netbios.NbtAddress +
  +
+
+

+P

+
+
PIPE_TYPE_CALL - +Static variable in class jcifs.smb.SmbNamedPipe +
Pipe operations should behave like the CallNamedPipe Win32 Named Pipe function. +
PIPE_TYPE_DCE_TRANSACT - +Static variable in class jcifs.smb.SmbNamedPipe +
  +
PIPE_TYPE_RDONLY - +Static variable in class jcifs.smb.SmbNamedPipe +
The pipe should be opened read-only. +
PIPE_TYPE_RDWR - +Static variable in class jcifs.smb.SmbNamedPipe +
The pipe should be opened for both reading and writing. +
PIPE_TYPE_TRANSACT - +Static variable in class jcifs.smb.SmbNamedPipe +
Pipe operations should behave like the TransactNamedPipe Win32 Named Pipe function. +
PIPE_TYPE_WRONLY - +Static variable in class jcifs.smb.SmbNamedPipe +
The pipe should be opened only for writing. +
P_NODE - +Static variable in class jcifs.netbios.NbtAddress +
A Point-to-Point node, or P node, unicasts queries to a nameserver + only. +
pathNamesPossiblyEqual(String, String) - +Method in class jcifs.smb.SmbFile +
  +
+
+

+R

+
+
RC4 - class jcifs.util.RC4.
 
RC4() - +Constructor for class jcifs.util.RC4 +
  +
RC4(byte[]) - +Constructor for class jcifs.util.RC4 +
  +
READ_CONTROL - +Static variable in class jcifs.smb.ACE +
  +
read() - +Method in class jcifs.smb.SmbFileInputStream +
Reads a byte of data from this input stream. +
read(byte[]) - +Method in class jcifs.smb.SmbFileInputStream +
Reads up to b.length bytes of data from this input stream into an array of bytes. +
read(byte[], int, int) - +Method in class jcifs.smb.SmbFileInputStream +
Reads up to len bytes of data from this input stream into an array of bytes. +
read() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
read(byte[]) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
read(byte[], int, int) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readBoolean() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readByte() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readChar() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readDirect(byte[], int, int) - +Method in class jcifs.smb.SmbFileInputStream +
  +
readDouble() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readFloat() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readFully(byte[]) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readFully(byte[], int, int) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readInt() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readLine() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readLong() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readShort() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readUTF() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readUnsignedByte() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
readUnsignedShort() - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
registerSmbURLHandler() - +Static method in class jcifs.Config +
This static method registers the SMB URL protocol handler which is + required to use SMB URLs with the java.net.URL class. +
renameTo(SmbFile) - +Method in class jcifs.smb.SmbFile +
Changes the name of the file this SmbFile represents to the name + designated by the SmbFile argument. +
requestNtlmPasswordAuthentication(String, SmbAuthException) - +Static method in class jcifs.smb.NtlmAuthenticator +
Used internally by jCIFS when an SmbAuthException is trapped to retrieve new user credentials. +
resolve(String, NtlmPasswordAuthentication) - +Method in class jcifs.smb.SID +
Manually resolve this SID. +
resolveSids(String, NtlmPasswordAuthentication, SID[], int, int) - +Static method in class jcifs.smb.SID +
  +
resolveSids(String, NtlmPasswordAuthentication, SID[]) - +Static method in class jcifs.smb.SID +
Resolve an array of SIDs using a cache and at most one MSRPC request. +
+
+

+S

+
+
SID - class jcifs.smb.SID.
A Windows SID is a numeric identifier used to represent Windows + accounts.
SID(byte[], int) - +Constructor for class jcifs.smb.SID +
  +
SID(String) - +Constructor for class jcifs.smb.SID +
Construct a SID from it's textual representation such as + S-1-5-21-1496946806-2192648263-3843101252-1029. +
SID(SID, int) - +Constructor for class jcifs.smb.SID +
Construct a SID from a domain SID and an RID + (relative identifier). +
SID(rpc.sid_t, int, String, String, boolean) - +Constructor for class jcifs.smb.SID +
  +
SID_FLAG_RESOLVE_SIDS - +Static variable in class jcifs.smb.SID +
  +
SID_TYPE_ALIAS - +Static variable in class jcifs.smb.SID +
  +
SID_TYPE_DELETED - +Static variable in class jcifs.smb.SID +
  +
SID_TYPE_DOMAIN - +Static variable in class jcifs.smb.SID +
  +
SID_TYPE_DOM_GRP - +Static variable in class jcifs.smb.SID +
  +
SID_TYPE_INVALID - +Static variable in class jcifs.smb.SID +
  +
SID_TYPE_UNKNOWN - +Static variable in class jcifs.smb.SID +
  +
SID_TYPE_USER - +Static variable in class jcifs.smb.SID +
  +
SID_TYPE_USE_NONE - +Static variable in class jcifs.smb.SID +
  +
SID_TYPE_WKN_GRP - +Static variable in class jcifs.smb.SID +
  +
SMBSERVER_NAME - +Static variable in class jcifs.netbios.NbtAddress +
A special generic name specified when connecting to a host for which + a name is not known. +
SYNCHRONIZE - +Static variable in class jcifs.smb.ACE +
  +
SYSTEM - +Static variable in class jcifs.smb.SID +
  +
SmbAuthException - exception jcifs.smb.SmbAuthException.
The SmbAuthException encapsulates the variety of + authentication related error codes returned by an SMB server.
SmbException - exception jcifs.smb.SmbException.
There are hundreds of error codes that may be returned by a CIFS + server.
SmbException(int, boolean) - +Constructor for class jcifs.smb.SmbException +
  +
SmbFile - class jcifs.smb.SmbFile.
This class represents a resource on an SMB network.
SmbFile(String) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a resource on an SMB network such as + a file or directory. +
SmbFile(SmbFile, String) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. +
SmbFile(String, String) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. +
SmbFile(String, NtlmPasswordAuthentication) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. +
SmbFile(String, NtlmPasswordAuthentication, int) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a file on an SMB network. +
SmbFile(String, String, NtlmPasswordAuthentication) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. +
SmbFile(String, String, NtlmPasswordAuthentication, int) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. +
SmbFile(SmbFile, String, int) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. +
SmbFile(URL) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory from a URL object. +
SmbFile(URL, NtlmPasswordAuthentication) - +Constructor for class jcifs.smb.SmbFile +
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory from a URL object and an + NtlmPasswordAuthentication object. +
SmbFileFilter - interface jcifs.smb.SmbFileFilter.
 
SmbFileInputStream - class jcifs.smb.SmbFileInputStream.
This InputStream can read bytes from a file on an SMB file server.
SmbFileInputStream(String) - +Constructor for class jcifs.smb.SmbFileInputStream +
Creates an InputStream for reading bytes from a file on + an SMB server addressed by the url parameter. +
SmbFileInputStream(SmbFile) - +Constructor for class jcifs.smb.SmbFileInputStream +
Creates an InputStream for reading bytes from a file on + an SMB server represented by the SmbFile parameter. +
SmbFileOutputStream - class jcifs.smb.SmbFileOutputStream.
This OutputStream can write bytes to a file on an SMB file server.
SmbFileOutputStream(String) - +Constructor for class jcifs.smb.SmbFileOutputStream +
Creates an OutputStream for writing to a file + on an SMB server addressed by the URL parameter. +
SmbFileOutputStream(SmbFile) - +Constructor for class jcifs.smb.SmbFileOutputStream +
Creates an OutputStream for writing bytes to a file on + an SMB server represented by the SmbFile parameter. +
SmbFileOutputStream(String, boolean) - +Constructor for class jcifs.smb.SmbFileOutputStream +
Creates an OutputStream for writing bytes to a file on an + SMB server addressed by the URL parameter. +
SmbFileOutputStream(SmbFile, boolean) - +Constructor for class jcifs.smb.SmbFileOutputStream +
Creates an OutputStream for writing bytes to a file + on an SMB server addressed by the SmbFile parameter. +
SmbFileOutputStream(String, int) - +Constructor for class jcifs.smb.SmbFileOutputStream +
Creates an OutputStream for writing bytes to a file + on an SMB server addressed by the SmbFile parameter. +
SmbFilenameFilter - interface jcifs.smb.SmbFilenameFilter.
 
SmbNamedPipe - class jcifs.smb.SmbNamedPipe.
This class will allow a Java program to read and write data to Named + Pipes and Transact NamedPipes.
SmbNamedPipe(String, int) - +Constructor for class jcifs.smb.SmbNamedPipe +
Open the Named Pipe resource specified by the url + parameter. +
SmbNamedPipe(String, int, NtlmPasswordAuthentication) - +Constructor for class jcifs.smb.SmbNamedPipe +
  +
SmbNamedPipe(URL, int, NtlmPasswordAuthentication) - +Constructor for class jcifs.smb.SmbNamedPipe +
  +
SmbRandomAccessFile - class jcifs.smb.SmbRandomAccessFile.
 
SmbRandomAccessFile(String, String, int) - +Constructor for class jcifs.smb.SmbRandomAccessFile +
  +
SmbRandomAccessFile(SmbFile, String) - +Constructor for class jcifs.smb.SmbRandomAccessFile +
  +
seToIoe(SmbException) - +Method in class jcifs.smb.SmbFileInputStream +
  +
seek(long) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
setAttributes(int) - +Method in class jcifs.smb.SmbFile +
Set the attributes of this file. +
setCreateTime(long) - +Method in class jcifs.smb.SmbFile +
Set the create time of the file. +
setDefault(NtlmAuthenticator) - +Static method in class jcifs.smb.NtlmAuthenticator +
Set the default NtlmAuthenticator. +
setInstance(PrintStream) - +Static method in class jcifs.util.LogStream +
This must be called before getInstance is called or + it will have no effect. +
setLastModified(long) - +Method in class jcifs.smb.SmbFile +
Set the last modified time of the file. +
setLength(long) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
setLevel(int) - +Static method in class jcifs.util.LogStream +
  +
setProperties(Properties) - +Static method in class jcifs.Config +
Set the default properties of the static Properties used by Config. +
setProperty(String, String) - +Static method in class jcifs.Config +
Add a property. +
setReadOnly() - +Method in class jcifs.smb.SmbFile +
Make this file read-only. +
setReadWrite() - +Method in class jcifs.smb.SmbFile +
Turn off the read-only attribute of this file. +
skip(long) - +Method in class jcifs.smb.SmbFileInputStream +
Skip n bytes of data on this stream. +
skipBytes(int) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
socketCount - +Static variable in class jcifs.Config +
  +
store(OutputStream, String) - +Static method in class jcifs.Config +
  +
+
+

+T

+
+
TYPE_COMM - +Static variable in class jcifs.smb.SmbFile +
Returned by SmbFile.getType() if the resource this SmbFile + represents is a communications device. +
TYPE_FILESYSTEM - +Static variable in class jcifs.smb.SmbFile +
Returned by SmbFile.getType() if the resource this SmbFile + represents is a regular file or directory. +
TYPE_NAMED_PIPE - +Static variable in class jcifs.smb.SmbFile +
Returned by SmbFile.getType() if the resource this SmbFile + represents is a named pipe. +
TYPE_PRINTER - +Static variable in class jcifs.smb.SmbFile +
Returned by SmbFile.getType() if the resource this SmbFile + represents is a printer. +
TYPE_SERVER - +Static variable in class jcifs.smb.SmbFile +
Returned by SmbFile.getType() if the resource this SmbFile + represents is a server. +
TYPE_SHARE - +Static variable in class jcifs.smb.SmbFile +
Returned by SmbFile.getType() if the resource this SmbFile + represents is a share. +
TYPE_WORKGROUP - +Static variable in class jcifs.smb.SmbFile +
Returned by SmbFile.getType() if the resource this SmbFile + represents is a workgroup. +
toByteArray(rpc.sid_t) - +Static method in class jcifs.smb.SID +
  +
toDisplayString() - +Method in class jcifs.smb.SID +
Return a String representing this SID ideal for display to + users. +
toString() - +Method in class jcifs.UniAddress +
Return the a text representation of this address such as + MYCOMPUTER/192.168.1.15. +
toString() - +Method in class jcifs.netbios.NbtAddress +
Returns the String representaion of this address. +
toString() - +Method in class jcifs.smb.ACE +
Return a string represeting this ACE. +
toString() - +Method in class jcifs.smb.NtlmContext +
  +
toString() - +Method in class jcifs.smb.NtlmPasswordAuthentication +
Return the domain and username in the format: + domain\\username. +
toString() - +Method in class jcifs.smb.SID +
Return the numeric representation of this sid such as + S-1-5-21-1496946806-2192648263-3843101252-1029. +
toString() - +Method in class jcifs.smb.SmbException +
  +
toString() - +Method in class jcifs.smb.SmbFile +
Returns the string representation of this SmbFile object. +
toURL() - +Method in class jcifs.smb.SmbFile +
Deprecated. Use getURL() instead +
+
+

+U

+
+
UniAddress - class jcifs.UniAddress.
Under normal conditions it is not necessary to use + this class to use jCIFS properly.
UniAddress(Object) - +Constructor for class jcifs.UniAddress +
Create a UniAddress by wrapping an InetAddress or + NbtAddress. +
update(byte[], int, int, byte[], int) - +Method in class jcifs.util.RC4 +
  +
+
+

+W

+
+
WRITE_DAC - +Static variable in class jcifs.smb.ACE +
  +
WRITE_OWNER - +Static variable in class jcifs.smb.ACE +
  +
wildcard - +Variable in class jcifs.smb.DosFileFilter +
  +
write(int) - +Method in class jcifs.smb.SmbFileOutputStream +
Writes the specified byte to this file output stream. +
write(byte[]) - +Method in class jcifs.smb.SmbFileOutputStream +
Writes b.length bytes from the specified byte array to this + file output stream. +
write(byte[], int, int) - +Method in class jcifs.smb.SmbFileOutputStream +
Writes len bytes from the specified byte array starting at + offset off to this file output stream. +
write(int) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
write(byte[]) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
write(byte[], int, int) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeBoolean(boolean) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeByte(int) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeBytes(String) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeChar(int) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeChars(String) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeDirect(byte[], int, int, int) - +Method in class jcifs.smb.SmbFileOutputStream +
Just bypasses TransWaitNamedPipe - used by DCERPC bind. +
writeDouble(double) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeFloat(float) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeInt(int) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeLong(long) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeShort(int) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
writeUTF(String) - +Method in class jcifs.smb.SmbRandomAccessFile +
  +
+
+A B C D E F G H I J L M N P R S T U W + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/index.html b/docs/api/index.html new file mode 100644 index 0000000..c63a385 --- /dev/null +++ b/docs/api/index.html @@ -0,0 +1,26 @@ + + + + + + +JCIFS API + + + + + + + + + +<H2> +Frame Alert</H2> + +<P> +This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. +<BR> +Link to<A HREF="overview-summary.html">Non-frame version.</A> + + + diff --git a/docs/api/jcifs/Config.html b/docs/api/jcifs/Config.html new file mode 100644 index 0000000..7aaa752 --- /dev/null +++ b/docs/api/jcifs/Config.html @@ -0,0 +1,662 @@ + + + + + + +Config (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs +
+Class Config

+
+java.lang.Object
+  extended byjcifs.Config
+
+
+
+
public class Config
extends java.lang.Object
+ +

+This class uses a static Properties to act + as a cental repository for all jCIFS configuration properties. It cannot be + instantiated. Similar to System properties the namespace + is global therefore property names should be unique. Before use, + the load method should be called with the name of a + Properties file (or null indicating no + file) to initialize the Config. The System + properties will then populate the Config as well potentially + overwriting properties from the file. Thus properties provided on the + commandline with the -Dproperty.name=value VM parameter + will override properties from the configuration file. +

+ There are several ways to set jCIFS properties. See + the overview page of the API + documentation for details. +

+ +

+


+ +

+ + + + + + + + + + + + + + + + + + +
+Field Summary
+static java.lang.StringDEFAULT_OEM_ENCODING + +
+           
+static intsocketCount + +
+           
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+static java.lang.Objectget(java.lang.String key) + +
+          Retrieve a property as an Object.
+static booleangetBoolean(java.lang.String key, + boolean def) + +
+          Retrieve a boolean value.
+static java.net.InetAddressgetInetAddress(java.lang.String key, + java.net.InetAddress def) + +
+          Retrieve an InetAddress.
+static java.net.InetAddress[]getInetAddressArray(java.lang.String key, + java.lang.String delim, + java.net.InetAddress[] def) + +
+          Retrieve an array of InetAddress created from a property + value containting a delim separated list of hostnames and/or + ipaddresses.
+static intgetInt(java.lang.String key) + +
+          Retrieve an int.
+static intgetInt(java.lang.String key, + int def) + +
+          Retrieve an int.
+static java.net.InetAddressgetLocalHost() + +
+           
+static longgetLong(java.lang.String key, + long def) + +
+          Retrieve a long.
+static java.lang.StringgetProperty(java.lang.String key) + +
+          Retrieve a String.
+static java.lang.StringgetProperty(java.lang.String key, + java.lang.String def) + +
+          Retrieve a String.
+static voidlist(java.io.PrintStream out) + +
+          List the properties in the Code.
+static voidload(java.io.InputStream in) + +
+          Load the Config with properties from the stream + in from a Properties file.
+static voidregisterSmbURLHandler() + +
+          This static method registers the SMB URL protocol handler which is + required to use SMB URLs with the java.net.URL class.
+static voidsetProperties(java.util.Properties prp) + +
+          Set the default properties of the static Properties used by Config.
+static java.lang.ObjectsetProperty(java.lang.String key, + java.lang.String value) + +
+          Add a property.
+static voidstore(java.io.OutputStream out, + java.lang.String header) + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Field Detail
+ +

+socketCount

+
+public static int socketCount
+
+
+
+
+
+ +

+DEFAULT_OEM_ENCODING

+
+public static java.lang.String DEFAULT_OEM_ENCODING
+
+
+
+
+ + + + + + + + + + + +
+Method Detail
+ +

+registerSmbURLHandler

+
+public static void registerSmbURLHandler()
+
+
This static method registers the SMB URL protocol handler which is + required to use SMB URLs with the java.net.URL class. If this + method is not called before attempting to create an SMB URL with the + URL class the following exception will occur: +
+ Exception MalformedURLException: unknown protocol: smb
+     at java.net.URL.(URL.java:480)
+     at java.net.URL.(URL.java:376)
+     at java.net.URL.(URL.java:330)
+     at jcifs.smb.SmbFile.(SmbFile.java:355)
+     ...
+ 
+

+

+
+
+
+
+ +

+setProperties

+
+public static void setProperties(java.util.Properties prp)
+
+
Set the default properties of the static Properties used by Config. This permits + a different Properties object/file to be used as the source of properties for + use by the jCIFS library. The Properties must be set before jCIFS + classes are accessed as most jCIFS classes load properties statically once. + Using this method will also override properties loaded + using the -Djcifs.properties= commandline parameter. +

+

+
+
+
+
+ +

+load

+
+public static void load(java.io.InputStream in)
+                 throws java.io.IOException
+
+
Load the Config with properties from the stream + in from a Properties file. +

+

+ +
Throws: +
java.io.IOException
+
+
+
+ +

+store

+
+public static void store(java.io.OutputStream out,
+                         java.lang.String header)
+                  throws java.io.IOException
+
+
+ +
Throws: +
java.io.IOException
+
+
+
+ +

+list

+
+public static void list(java.io.PrintStream out)
+                 throws java.io.IOException
+
+
List the properties in the Code. +

+

+ +
Throws: +
java.io.IOException
+
+
+
+ +

+setProperty

+
+public static java.lang.Object setProperty(java.lang.String key,
+                                           java.lang.String value)
+
+
Add a property. +

+

+
+
+
+
+ +

+get

+
+public static java.lang.Object get(java.lang.String key)
+
+
Retrieve a property as an Object. +

+

+
+
+
+
+ +

+getProperty

+
+public static java.lang.String getProperty(java.lang.String key,
+                                           java.lang.String def)
+
+
Retrieve a String. If the key cannot be found, + the provided def default parameter will be returned. +

+

+
+
+
+
+ +

+getProperty

+
+public static java.lang.String getProperty(java.lang.String key)
+
+
Retrieve a String. If the property is not found, null is returned. +

+

+
+
+
+
+ +

+getInt

+
+public static int getInt(java.lang.String key,
+                         int def)
+
+
Retrieve an int. If the key does not exist or + cannot be converted to an int, the provided default + argument will be returned. +

+

+
+
+
+
+ +

+getInt

+
+public static int getInt(java.lang.String key)
+
+
Retrieve an int. If the property is not found, -1 is returned. +

+

+
+
+
+
+ +

+getLong

+
+public static long getLong(java.lang.String key,
+                           long def)
+
+
Retrieve a long. If the key does not exist or + cannot be converted to a long, the provided default + argument will be returned. +

+

+
+
+
+
+ +

+getInetAddress

+
+public static java.net.InetAddress getInetAddress(java.lang.String key,
+                                                  java.net.InetAddress def)
+
+
Retrieve an InetAddress. If the address is not + an IP address and cannot be resolved null will + be returned. +

+

+
+
+
+
+ +

+getLocalHost

+
+public static java.net.InetAddress getLocalHost()
+
+
+
+
+
+
+ +

+getBoolean

+
+public static boolean getBoolean(java.lang.String key,
+                                 boolean def)
+
+
Retrieve a boolean value. If the property is not found, the value of def is returned. +

+

+
+
+
+
+ +

+getInetAddressArray

+
+public static java.net.InetAddress[] getInetAddressArray(java.lang.String key,
+                                                         java.lang.String delim,
+                                                         java.net.InetAddress[] def)
+
+
Retrieve an array of InetAddress created from a property + value containting a delim separated list of hostnames and/or + ipaddresses. +

+

+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/UniAddress.html b/docs/api/jcifs/UniAddress.html new file mode 100644 index 0000000..6dc0f05 --- /dev/null +++ b/docs/api/jcifs/UniAddress.html @@ -0,0 +1,506 @@ + + + + + + +UniAddress (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs +
+Class UniAddress

+
+java.lang.Object
+  extended byjcifs.UniAddress
+
+
+
+
public class UniAddress
extends java.lang.Object
+ +

+

Under normal conditions it is not necessary to use + this class to use jCIFS properly. Name resolusion is + handled internally to the jcifs.smb package. +

+ This class is a wrapper for both NbtAddress + and InetAddress. The name resolution mechanisms + used will systematically query all available configured resolution + services including WINS, broadcasts, DNS, and LMHOSTS. See + Setting Name Resolution Properties + and the jcifs.resolveOrder property. Changing + jCIFS name resolution properties can greatly affect the behavior of + the client and may be necessary for proper operation. +

+ This class should be used in favor of InetAddress to resolve + hostnames on LANs and WANs that support a mixture of NetBIOS/WINS and + DNS resolvable hosts. +

+ +

+


+ +

+ + + + + + + + + + + + + + + + +
+Constructor Summary
UniAddress(java.lang.Object addr) + +
+          Create a UniAddress by wrapping an InetAddress or + NbtAddress.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanequals(java.lang.Object obj) + +
+          Compare two addresses for equality.
+ java.lang.StringfirstCalledName() + +
+          Guess first called name to try for session establishment.
+ java.lang.ObjectgetAddress() + +
+          Return the underlying NbtAddress or InetAddress.
+static UniAddress[]getAllByName(java.lang.String hostname, + boolean possibleNTDomainOrWorkgroup) + +
+           
+static UniAddressgetByName(java.lang.String hostname) + +
+          Determines the address of a host given it's host name.
+static UniAddressgetByName(java.lang.String hostname, + boolean possibleNTDomainOrWorkgroup) + +
+          Lookup hostname and return it's UniAddress.
+ java.lang.StringgetHostAddress() + +
+          Return the IP address as text such as "192.168.1.15".
+ java.lang.StringgetHostName() + +
+          Return the hostname of this address such as "MYCOMPUTER".
+ inthashCode() + +
+          Return the IP address of this address as a 32 bit integer.
+ java.lang.StringnextCalledName() + +
+          Guess next called name to try for session establishment.
+ java.lang.StringtoString() + +
+          Return the a text representation of this address such as + MYCOMPUTER/192.168.1.15.
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+UniAddress

+
+public UniAddress(java.lang.Object addr)
+
+
Create a UniAddress by wrapping an InetAddress or + NbtAddress. +

+

+ + + + + + + + +
+Method Detail
+ +

+getByName

+
+public static UniAddress getByName(java.lang.String hostname)
+                            throws java.net.UnknownHostException
+
+
Determines the address of a host given it's host name. The name can be a + machine name like "jcifs.samba.org", or an IP address like "192.168.1.15". +

+

+
Parameters:
hostname - NetBIOS or DNS hostname to resolve +
Throws: +
java.net.UnknownHostException - if there is an error resolving the name
+
+
+
+ +

+getByName

+
+public static UniAddress getByName(java.lang.String hostname,
+                                   boolean possibleNTDomainOrWorkgroup)
+                            throws java.net.UnknownHostException
+
+
Lookup hostname and return it's UniAddress. If the + possibleNTDomainOrWorkgroup parameter is true an + addtional name query will be performed to locate a master browser. +

+

+ +
Throws: +
java.net.UnknownHostException
+
+
+
+ +

+getAllByName

+
+public static UniAddress[] getAllByName(java.lang.String hostname,
+                                        boolean possibleNTDomainOrWorkgroup)
+                                 throws java.net.UnknownHostException
+
+
+ +
Throws: +
java.net.UnknownHostException
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
Return the IP address of this address as a 32 bit integer. +

+

+
+
+
+
+ +

+equals

+
+public boolean equals(java.lang.Object obj)
+
+
Compare two addresses for equality. Two UniAddresss are equal + if they are both UniAddress' and refer to the same IP address. +

+

+
+
+
+
+ +

+firstCalledName

+
+public java.lang.String firstCalledName()
+
+
Guess first called name to try for session establishment. This + method is used exclusively by the jcifs.smb package. +

+

+
+
+
+
+ +

+nextCalledName

+
+public java.lang.String nextCalledName()
+
+
Guess next called name to try for session establishment. This + method is used exclusively by the jcifs.smb package. +

+

+
+
+
+
+ +

+getAddress

+
+public java.lang.Object getAddress()
+
+
Return the underlying NbtAddress or InetAddress. +

+

+
+
+
+
+ +

+getHostName

+
+public java.lang.String getHostName()
+
+
Return the hostname of this address such as "MYCOMPUTER". +

+

+
+
+
+
+ +

+getHostAddress

+
+public java.lang.String getHostAddress()
+
+
Return the IP address as text such as "192.168.1.15". +

+

+
+
+
+
+ +

+toString

+
+public java.lang.String toString()
+
+
Return the a text representation of this address such as + MYCOMPUTER/192.168.1.15. +

+

+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/class-use/Config.html b/docs/api/jcifs/class-use/Config.html new file mode 100644 index 0000000..f6f3de4 --- /dev/null +++ b/docs/api/jcifs/class-use/Config.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.Config (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.Config

+
+No usage of jcifs.Config +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/class-use/UniAddress.html b/docs/api/jcifs/class-use/UniAddress.html new file mode 100644 index 0000000..ab76fe9 --- /dev/null +++ b/docs/api/jcifs/class-use/UniAddress.html @@ -0,0 +1,190 @@ + + + + + + +Uses of Class jcifs.UniAddress (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.UniAddress

+
+ + + + + + + + + +
+Packages that use UniAddress
jcifs  
+  +

+ + + + + +
+Uses of UniAddress in jcifs
+  +

+ + + + + + + + + + + + + + + + + +
Methods in jcifs that return UniAddress
+static UniAddressUniAddress.getByName(java.lang.String hostname) + +
+          Determines the address of a host given it's host name.
+static UniAddressUniAddress.getByName(java.lang.String hostname, + boolean possibleNTDomainOrWorkgroup) + +
+          Lookup hostname and return it's UniAddress.
+static UniAddress[]UniAddress.getAllByName(java.lang.String hostname, + boolean possibleNTDomainOrWorkgroup) + +
+           
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/netbios/NbtAddress.html b/docs/api/jcifs/netbios/NbtAddress.html new file mode 100644 index 0000000..6b3455a --- /dev/null +++ b/docs/api/jcifs/netbios/NbtAddress.html @@ -0,0 +1,1083 @@ + + + + + + +NbtAddress (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.netbios +
+Class NbtAddress

+
+java.lang.Object
+  extended byjcifs.netbios.NbtAddress
+
+
+
+
public final class NbtAddress
extends java.lang.Object
+ +

+This class represents a NetBIOS over TCP/IP address. Under normal + conditions, users of jCIFS need not be concerned with this class as + name resolution and session services are handled internally by the smb package. + +

Applications can use the methods getLocalHost, + getByName, and + getAllByAddress to create a new NbtAddress instance. This + class is symmetric with InetAddress. + +

About NetBIOS: The NetBIOS name + service is a dynamic distributed service that allows hosts to resolve + names by broadcasting a query, directing queries to a server such as + Samba or WINS. NetBIOS is currently the primary networking layer for + providing name service, datagram service, and session service to the + Microsoft Windows platform. A NetBIOS name can be 15 characters long + and hosts usually registers several names on the network. From a + Windows command prompt you can see + what names a host registers with the nbtstat command. +

+ C:\>nbtstat -a 192.168.1.15
+ 
+        NetBIOS Remote Machine Name Table
+ 
+    Name               Type         Status
+ ---------------------------------------------
+ JMORRIS2        <00>  UNIQUE      Registered
+ BILLING-NY      <00>  GROUP       Registered
+ JMORRIS2        <03>  UNIQUE      Registered
+ JMORRIS2        <20>  UNIQUE      Registered
+ BILLING-NY      <1E>  GROUP       Registered
+ JMORRIS         <03>  UNIQUE      Registered
+ 
+ MAC Address = 00-B0-34-21-FA-3B
+ 
+

The hostname of this machine is JMORRIS2. It is + a member of the group(a.k.a workgroup and domain) BILLING-NY. To + obtain an InetAddress for a host one might do: + +

+   InetAddress addr = NbtAddress.getByName( "jmorris2" ).getInetAddress();
+ 
+

From a UNIX platform with Samba installed you can perform similar + diagnostics using the nmblookup utility. +

+ +

+

+
Since:
+
jcifs-0.1
+
Author:
+
Michael B. Allen
+
See Also:
InetAddress
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Field Summary
+static intB_NODE + +
+          A B node only broadcasts name queries.
+static intH_NODE + +
+          A Hybrid node tries to resolve a name using the nameserver first.
+static intM_NODE + +
+          Try Broadcast queries first, then try to resolve the name using the + nameserver.
+static java.lang.StringMASTER_BROWSER_NAME + +
+          This is a special name for querying the master browser that serves the + list of hosts found in "Network Neighborhood".
+static intP_NODE + +
+          A Point-to-Point node, or P node, unicasts queries to a nameserver + only.
+static java.lang.StringSMBSERVER_NAME + +
+          A special generic name specified when connecting to a host for which + a name is not known.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanequals(java.lang.Object obj) + +
+          Determines if this address is equal two another.
+ java.lang.StringfirstCalledName() + +
+           
+ byte[]getAddress() + +
+          Returns the raw IP address of this NbtAddress.
+static NbtAddress[]getAllByAddress(NbtAddress addr) + +
+          Retrieve all addresses of a host by it's address.
+static NbtAddress[]getAllByAddress(java.lang.String host) + +
+          Retrieve all addresses of a host by it's address.
+static NbtAddress[]getAllByAddress(java.lang.String host, + int type, + java.lang.String scope) + +
+          Retrieve all addresses of a host by it's address.
+static NbtAddress[]getAllByName(java.lang.String host, + int type, + java.lang.String scope, + java.net.InetAddress svr) + +
+           
+static NbtAddressgetByName(java.lang.String host) + +
+          Determines the address of a host given it's host name.
+static NbtAddressgetByName(java.lang.String host, + int type, + java.lang.String scope) + +
+          Determines the address of a host given it's host name.
+static NbtAddressgetByName(java.lang.String host, + int type, + java.lang.String scope, + java.net.InetAddress svr) + +
+           
+ java.lang.StringgetHostAddress() + +
+          Returns this IP adress as a String in the form "%d.%d.%d.%d".
+ java.lang.StringgetHostName() + +
+          The hostname of this address.
+ java.net.InetAddressgetInetAddress() + +
+          To convert this address to an InetAddress.
+static NbtAddressgetLocalHost() + +
+          Retrieves the local host address.
+static jcifs.netbios.NamegetLocalName() + +
+           
+ byte[]getMacAddress() + +
+          Retrieves the MAC address of the remote network interface.
+ intgetNameType() + +
+          Returned the hex code associated with this name(e.g.
+ intgetNodeType() + +
+          Checks the node type of this address.
+static java.net.InetAddressgetWINSAddress() + +
+           
+ inthashCode() + +
+          Returns a hashcode for this IP address.
+ booleanisActive() + +
+          Determines if this address is active.
+ booleanisBeingDeleted() + +
+          Determines if this address in the process of being deleted.
+ booleanisGroupAddress() + +
+          Determines if the address is a group address.
+ booleanisInConflict() + +
+          Determines if this address in conflict with another address.
+ booleanisPermanent() + +
+          Determines if this address is set to be permanent.
+static booleanisWINS(java.net.InetAddress svr) + +
+           
+ java.lang.StringnextCalledName() + +
+           
+ java.lang.StringtoString() + +
+          Returns the String representaion of this address.
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Field Detail
+ +

+MASTER_BROWSER_NAME

+
+public static final java.lang.String MASTER_BROWSER_NAME
+
+
This is a special name for querying the master browser that serves the + list of hosts found in "Network Neighborhood". +

+

+
See Also:
Constant Field Values
+
+
+ +

+SMBSERVER_NAME

+
+public static final java.lang.String SMBSERVER_NAME
+
+
A special generic name specified when connecting to a host for which + a name is not known. Not all servers respond to this name. +

+

+
See Also:
Constant Field Values
+
+
+ +

+B_NODE

+
+public static final int B_NODE
+
+
A B node only broadcasts name queries. This is the default if a + nameserver such as WINS or Samba is not specified. +

+

+
See Also:
Constant Field Values
+
+
+ +

+P_NODE

+
+public static final int P_NODE
+
+
A Point-to-Point node, or P node, unicasts queries to a nameserver + only. Natrually the jcifs.netbios.nameserver property must + be set. +

+

+
See Also:
Constant Field Values
+
+
+ +

+M_NODE

+
+public static final int M_NODE
+
+
Try Broadcast queries first, then try to resolve the name using the + nameserver. +

+

+
See Also:
Constant Field Values
+
+
+ +

+H_NODE

+
+public static final int H_NODE
+
+
A Hybrid node tries to resolve a name using the nameserver first. If + that fails use the broadcast address. This is the default if a nameserver + is provided. This is the behavior of Microsoft Windows machines. +

+

+
See Also:
Constant Field Values
+
+ + + + + + + + + + + +
+Method Detail
+ +

+getLocalHost

+
+public static NbtAddress getLocalHost()
+                               throws java.net.UnknownHostException
+
+
Retrieves the local host address. +

+

+ +
Throws: +
java.net.UnknownHostException - This is not likely as the IP returned + by InetAddress should be available
+
+
+
+ +

+getLocalName

+
+public static jcifs.netbios.Name getLocalName()
+
+
+
+
+
+
+ +

+getByName

+
+public static NbtAddress getByName(java.lang.String host)
+                            throws java.net.UnknownHostException
+
+
Determines the address of a host given it's host name. The name can be a NetBIOS name like + "freto" or an IP address like "192.168.1.15". It cannot be a DNS name; + the analygous UniAddress or InetAddress + getByName methods can be used for that. +

+

+
Parameters:
host - hostname to resolve +
Throws: +
java.net.UnknownHostException - if there is an error resolving the name
+
+
+
+ +

+getByName

+
+public static NbtAddress getByName(java.lang.String host,
+                                   int type,
+                                   java.lang.String scope)
+                            throws java.net.UnknownHostException
+
+
Determines the address of a host given it's host name. NetBIOS + names also have a type. Types(aka Hex Codes) + are used to distiquish the various services on a host. Here is + a fairly complete list of NetBIOS hex codes. Scope is not used but is + still functional in other NetBIOS products and so for completeness it has been + implemented. A scope of null or "" + signifies no scope. +

+

+
Parameters:
host - the name to resolve
type - the hex code of the name
scope - the scope of the name +
Throws: +
java.net.UnknownHostException - if there is an error resolving the name
+
+
+
+ +

+getByName

+
+public static NbtAddress getByName(java.lang.String host,
+                                   int type,
+                                   java.lang.String scope,
+                                   java.net.InetAddress svr)
+                            throws java.net.UnknownHostException
+
+
+ +
Throws: +
java.net.UnknownHostException
+
+
+
+ +

+getAllByName

+
+public static NbtAddress[] getAllByName(java.lang.String host,
+                                        int type,
+                                        java.lang.String scope,
+                                        java.net.InetAddress svr)
+                                 throws java.net.UnknownHostException
+
+
+ +
Throws: +
java.net.UnknownHostException
+
+
+
+ +

+getAllByAddress

+
+public static NbtAddress[] getAllByAddress(java.lang.String host)
+                                    throws java.net.UnknownHostException
+
+
Retrieve all addresses of a host by it's address. NetBIOS hosts can + have many names for a given IP address. The name and IP address make the + NetBIOS address. This provides a way to retrieve the other names for a + host with the same IP address. +

+

+
Parameters:
host - hostname to lookup all addresses for +
Throws: +
java.net.UnknownHostException - if there is an error resolving the name
+
+
+
+ +

+getAllByAddress

+
+public static NbtAddress[] getAllByAddress(java.lang.String host,
+                                           int type,
+                                           java.lang.String scope)
+                                    throws java.net.UnknownHostException
+
+
Retrieve all addresses of a host by it's address. NetBIOS hosts can + have many names for a given IP address. The name and IP address make + the NetBIOS address. This provides a way to retrieve the other names + for a host with the same IP address. See getByName(java.lang.String) + for a description of type + and scope. +

+

+
Parameters:
host - hostname to lookup all addresses for
type - the hexcode of the name
scope - the scope of the name +
Throws: +
java.net.UnknownHostException - if there is an error resolving the name
+
+
+
+ +

+getAllByAddress

+
+public static NbtAddress[] getAllByAddress(NbtAddress addr)
+                                    throws java.net.UnknownHostException
+
+
Retrieve all addresses of a host by it's address. NetBIOS hosts can + have many names for a given IP address. The name and IP address make the + NetBIOS address. This provides a way to retrieve the other names for a + host with the same IP address. +

+

+
Parameters:
addr - the address to query +
Throws: +
java.net.UnknownHostException - if address cannot be resolved
+
+
+
+ +

+getWINSAddress

+
+public static java.net.InetAddress getWINSAddress()
+
+
+
+
+
+
+ +

+isWINS

+
+public static boolean isWINS(java.net.InetAddress svr)
+
+
+
+
+
+
+ +

+firstCalledName

+
+public java.lang.String firstCalledName()
+
+
+
+
+
+
+ +

+nextCalledName

+
+public java.lang.String nextCalledName()
+
+
+
+
+
+
+ +

+isGroupAddress

+
+public boolean isGroupAddress()
+                       throws java.net.UnknownHostException
+
+
Determines if the address is a group address. This is also + known as a workgroup name or group name. +

+

+ +
Throws: +
java.net.UnknownHostException - if the host cannot be resolved to find out.
+
+
+
+ +

+getNodeType

+
+public int getNodeType()
+                throws java.net.UnknownHostException
+
+
Checks the node type of this address. +

+

+ +
Returns:
B_NODE, + P_NODE, M_NODE, + H_NODE +
Throws: +
java.net.UnknownHostException - if the host cannot be resolved to find out.
+
+
+
+ +

+isBeingDeleted

+
+public boolean isBeingDeleted()
+                       throws java.net.UnknownHostException
+
+
Determines if this address in the process of being deleted. +

+

+ +
Throws: +
java.net.UnknownHostException - if the host cannot be resolved to find out.
+
+
+
+ +

+isInConflict

+
+public boolean isInConflict()
+                     throws java.net.UnknownHostException
+
+
Determines if this address in conflict with another address. +

+

+ +
Throws: +
java.net.UnknownHostException - if the host cannot be resolved to find out.
+
+
+
+ +

+isActive

+
+public boolean isActive()
+                 throws java.net.UnknownHostException
+
+
Determines if this address is active. +

+

+ +
Throws: +
java.net.UnknownHostException - if the host cannot be resolved to find out.
+
+
+
+ +

+isPermanent

+
+public boolean isPermanent()
+                    throws java.net.UnknownHostException
+
+
Determines if this address is set to be permanent. +

+

+ +
Throws: +
java.net.UnknownHostException - if the host cannot be resolved to find out.
+
+
+
+ +

+getMacAddress

+
+public byte[] getMacAddress()
+                     throws java.net.UnknownHostException
+
+
Retrieves the MAC address of the remote network interface. Samba returns all zeros. +

+

+ +
Returns:
the MAC address as an array of six bytes +
Throws: +
java.net.UnknownHostException - if the host cannot be resolved to + determine the MAC address.
+
+
+
+ +

+getHostName

+
+public java.lang.String getHostName()
+
+
The hostname of this address. If the hostname is null the local machines + IP address is returned. +

+

+ +
Returns:
the text representation of the hostname associated with this address
+
+
+
+ +

+getAddress

+
+public byte[] getAddress()
+
+
Returns the raw IP address of this NbtAddress. The result is in network + byte order: the highest order byte of the address is in getAddress()[0]. +

+

+ +
Returns:
a four byte array
+
+
+
+ +

+getInetAddress

+
+public java.net.InetAddress getInetAddress()
+                                    throws java.net.UnknownHostException
+
+
To convert this address to an InetAddress. +

+

+ +
Returns:
the InetAddress representation of this address. +
Throws: +
java.net.UnknownHostException
+
+
+
+ +

+getHostAddress

+
+public java.lang.String getHostAddress()
+
+
Returns this IP adress as a String in the form "%d.%d.%d.%d". +

+

+
+
+
+
+ +

+getNameType

+
+public int getNameType()
+
+
Returned the hex code associated with this name(e.g. 0x20 is for the file service) +

+

+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
Returns a hashcode for this IP address. The hashcode comes from the IP address + and is not generated from the string representation. So because NetBIOS nodes + can have many names, all names associated with an IP will have the same + hashcode. +

+

+
+
+
+
+ +

+equals

+
+public boolean equals(java.lang.Object obj)
+
+
Determines if this address is equal two another. Only the IP Addresses + are compared. Similar to the hashCode() method, the comparison + is based on the integer IP address and not the string representation. +

+

+
+
+
+
+ +

+toString

+
+public java.lang.String toString()
+
+
Returns the String representaion of this address. +

+

+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/netbios/class-use/NbtAddress.html b/docs/api/jcifs/netbios/class-use/NbtAddress.html new file mode 100644 index 0000000..e840bf8 --- /dev/null +++ b/docs/api/jcifs/netbios/class-use/NbtAddress.html @@ -0,0 +1,254 @@ + + + + + + +Uses of Class jcifs.netbios.NbtAddress (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.netbios.NbtAddress

+
+ + + + + + + + + +
+Packages that use NbtAddress
jcifs.netbios  
+  +

+ + + + + +
+Uses of NbtAddress in jcifs.netbios
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in jcifs.netbios that return NbtAddress
+static NbtAddressNbtAddress.getLocalHost() + +
+          Retrieves the local host address.
+static NbtAddressNbtAddress.getByName(java.lang.String host) + +
+          Determines the address of a host given it's host name.
+static NbtAddressNbtAddress.getByName(java.lang.String host, + int type, + java.lang.String scope) + +
+          Determines the address of a host given it's host name.
+static NbtAddressNbtAddress.getByName(java.lang.String host, + int type, + java.lang.String scope, + java.net.InetAddress svr) + +
+           
+static NbtAddress[]NbtAddress.getAllByName(java.lang.String host, + int type, + java.lang.String scope, + java.net.InetAddress svr) + +
+           
+static NbtAddress[]NbtAddress.getAllByAddress(java.lang.String host) + +
+          Retrieve all addresses of a host by it's address.
+static NbtAddress[]NbtAddress.getAllByAddress(java.lang.String host, + int type, + java.lang.String scope) + +
+          Retrieve all addresses of a host by it's address.
+static NbtAddress[]NbtAddress.getAllByAddress(NbtAddress addr) + +
+          Retrieve all addresses of a host by it's address.
+  +

+ + + + + + + + + +
Methods in jcifs.netbios with parameters of type NbtAddress
+static NbtAddress[]NbtAddress.getAllByAddress(NbtAddress addr) + +
+          Retrieve all addresses of a host by it's address.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/netbios/package-frame.html b/docs/api/jcifs/netbios/package-frame.html new file mode 100644 index 0000000..7f813c2 --- /dev/null +++ b/docs/api/jcifs/netbios/package-frame.html @@ -0,0 +1,32 @@ + + + + + + +jcifs.netbios (JCIFS API) + + + + + + + + + + + +jcifs.netbios + + + + +
+Classes  + +
+NbtAddress
+ + + + diff --git a/docs/api/jcifs/netbios/package-summary.html b/docs/api/jcifs/netbios/package-summary.html new file mode 100644 index 0000000..a3633f5 --- /dev/null +++ b/docs/api/jcifs/netbios/package-summary.html @@ -0,0 +1,148 @@ + + + + + + +jcifs.netbios (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package jcifs.netbios +

+ + + + + + + + + +
+Class Summary
NbtAddressThis class represents a NetBIOS over TCP/IP address.
+  + +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/netbios/package-tree.html b/docs/api/jcifs/netbios/package-tree.html new file mode 100644 index 0000000..1654e6a --- /dev/null +++ b/docs/api/jcifs/netbios/package-tree.html @@ -0,0 +1,145 @@ + + + + + + +jcifs.netbios Class Hierarchy (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package jcifs.netbios +

+
+
+
Package Hierarchies:
All Packages
+
+

+Class Hierarchy +

+
    +
  • class java.lang.Object +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/netbios/package-use.html b/docs/api/jcifs/netbios/package-use.html new file mode 100644 index 0000000..b018a2c --- /dev/null +++ b/docs/api/jcifs/netbios/package-use.html @@ -0,0 +1,162 @@ + + + + + + +Uses of Package jcifs.netbios (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
jcifs.netbios

+
+ + + + + + + + + +
+Packages that use jcifs.netbios
jcifs.netbios  
+  +

+ + + + + + + + +
+Classes in jcifs.netbios used by jcifs.netbios
NbtAddress + +
+          This class represents a NetBIOS over TCP/IP address.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/package-frame.html b/docs/api/jcifs/package-frame.html new file mode 100644 index 0000000..508b4d4 --- /dev/null +++ b/docs/api/jcifs/package-frame.html @@ -0,0 +1,34 @@ + + + + + + +jcifs (JCIFS API) + + + + + + + + + + + +jcifs + + + + +
+Classes  + +
+Config +
+UniAddress
+ + + + diff --git a/docs/api/jcifs/package-summary.html b/docs/api/jcifs/package-summary.html new file mode 100644 index 0000000..6838b5f --- /dev/null +++ b/docs/api/jcifs/package-summary.html @@ -0,0 +1,154 @@ + + + + + + +jcifs (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package jcifs +

+ + + + + + + + + + + + + +
+Class Summary
ConfigThis class uses a static Properties to act + as a cental repository for all jCIFS configuration properties.
UniAddressUnder normal conditions it is not necessary to use + this class to use jCIFS properly.
+  + +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/package-tree.html b/docs/api/jcifs/package-tree.html new file mode 100644 index 0000000..f538f03 --- /dev/null +++ b/docs/api/jcifs/package-tree.html @@ -0,0 +1,145 @@ + + + + + + +jcifs Class Hierarchy (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package jcifs +

+
+
+
Package Hierarchies:
All Packages
+
+

+Class Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/package-use.html b/docs/api/jcifs/package-use.html new file mode 100644 index 0000000..20d3b51 --- /dev/null +++ b/docs/api/jcifs/package-use.html @@ -0,0 +1,163 @@ + + + + + + +Uses of Package jcifs (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
jcifs

+
+ + + + + + + + + +
+Packages that use jcifs
jcifs  
+  +

+ + + + + + + + +
+Classes in jcifs used by jcifs
UniAddress + +
+          Under normal conditions it is not necessary to use + this class to use jCIFS properly.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/ACE.html b/docs/api/jcifs/smb/ACE.html new file mode 100644 index 0000000..00833ce --- /dev/null +++ b/docs/api/jcifs/smb/ACE.html @@ -0,0 +1,864 @@ + + + + + + +ACE (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class ACE

+
+java.lang.Object
+  extended byjcifs.smb.ACE
+
+
+
+
public class ACE
extends java.lang.Object
+ +

+An Access Control Entry (ACE) is an element in a security descriptor + such as those associated with files and directories. The Windows OS + determines which users have the necessary permissions to access objects + based on these entries. +

+ To fully understand the information exposed by this class a description + of the access check algorithm used by Windows is required. The following + is a basic description of the algorithm. For a more complete description + we recommend reading the section on Access Control in Keith Brown's + "The .NET Developer's Guide to Windows Security" (which is also + available online). +

+ Direct ACEs are evaluated first in order. The SID of the user performing + the operation and the desired access bits are compared to the SID + and access mask of each ACE. If the SID matches, the allow/deny flags + and access mask are considered. If the ACE is a "deny" + ACE and any of the desired access bits match bits in the access + mask of the ACE, the whole access check fails. If the ACE is an "allow" + ACE and all of the bits in the desired access bits match bits in + the access mask of the ACE, the access check is successful. Otherwise, + more ACEs are evaluated until all desired access bits (combined) + are "allowed". If all of the desired access bits are not "allowed" + the then same process is repeated for inherited ACEs. +

+ For example, if user WNET\alice tries to open a file + with desired access bits 0x00000003 (FILE_READ_DATA | + FILE_WRITE_DATA) and the target file has the following security + descriptor ACEs: +

+ Allow WNET\alice     0x001200A9  Direct
+ Allow Administrators 0x001F01FF  Inherited
+ Allow SYSTEM         0x001F01FF  Inherited
+ 
+ the access check would fail because the direct ACE has an access mask + of 0x001200A9 which doesn't have the + FILE_WRITE_DATA bit on (bit 0x00000002). Actually, this isn't quite correct. If + WNET\alice is in the local Administrators group the access check + will succeed because the inherited ACE allows local Administrators + both FILE_READ_DATA and FILE_WRITE_DATA access. +

+ +

+


+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Field Summary
+static intDELETE + +
+           
+static intFILE_APPEND_DATA + +
+           
+static intFILE_DELETE + +
+           
+static intFILE_EXECUTE + +
+           
+static intFILE_READ_ATTRIBUTES + +
+           
+static intFILE_READ_DATA + +
+           
+static intFILE_READ_EA + +
+           
+static intFILE_WRITE_ATTRIBUTES + +
+           
+static intFILE_WRITE_DATA + +
+           
+static intFILE_WRITE_EA + +
+           
+static intFLAGS_CONTAINER_INHERIT + +
+           
+static intFLAGS_INHERIT_ONLY + +
+           
+static intFLAGS_INHERITED + +
+           
+static intFLAGS_NO_PROPAGATE + +
+           
+static intFLAGS_OBJECT_INHERIT + +
+           
+static intGENERIC_ALL + +
+           
+static intGENERIC_EXECUTE + +
+           
+static intGENERIC_READ + +
+           
+static intGENERIC_WRITE + +
+           
+static intREAD_CONTROL + +
+           
+static intSYNCHRONIZE + +
+           
+static intWRITE_DAC + +
+           
+static intWRITE_OWNER + +
+           
+  + + + + + + + + + + +
+Constructor Summary
ACE() + +
+           
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ intgetAccessMask() + +
+          Returns the access mask accociated with this ACE.
+ java.lang.StringgetApplyToText() + +
+          Returns the 'Apply To' text for inheritance of ACEs on + directories such as 'This folder, subfolder and files'.
+ intgetFlags() + +
+          Returns the flags for this ACE.
+ SIDgetSID() + +
+          Return the SID associated with this ACE.
+ booleanisAllow() + +
+          Returns true if this ACE is an allow ACE and false if it is a deny ACE.
+ booleanisInherited() + +
+          Returns true if this ACE is an inherited ACE and false if it is a direct ACE.
+ java.lang.StringtoString() + +
+          Return a string represeting this ACE.
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Field Detail
+ +

+FILE_READ_DATA

+
+public static final int FILE_READ_DATA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_WRITE_DATA

+
+public static final int FILE_WRITE_DATA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_APPEND_DATA

+
+public static final int FILE_APPEND_DATA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_READ_EA

+
+public static final int FILE_READ_EA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_WRITE_EA

+
+public static final int FILE_WRITE_EA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_EXECUTE

+
+public static final int FILE_EXECUTE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_DELETE

+
+public static final int FILE_DELETE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_READ_ATTRIBUTES

+
+public static final int FILE_READ_ATTRIBUTES
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_WRITE_ATTRIBUTES

+
+public static final int FILE_WRITE_ATTRIBUTES
+
+
+
See Also:
Constant Field Values
+
+
+ +

+DELETE

+
+public static final int DELETE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+READ_CONTROL

+
+public static final int READ_CONTROL
+
+
+
See Also:
Constant Field Values
+
+
+ +

+WRITE_DAC

+
+public static final int WRITE_DAC
+
+
+
See Also:
Constant Field Values
+
+
+ +

+WRITE_OWNER

+
+public static final int WRITE_OWNER
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SYNCHRONIZE

+
+public static final int SYNCHRONIZE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+GENERIC_ALL

+
+public static final int GENERIC_ALL
+
+
+
See Also:
Constant Field Values
+
+
+ +

+GENERIC_EXECUTE

+
+public static final int GENERIC_EXECUTE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+GENERIC_WRITE

+
+public static final int GENERIC_WRITE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+GENERIC_READ

+
+public static final int GENERIC_READ
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_OBJECT_INHERIT

+
+public static final int FLAGS_OBJECT_INHERIT
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_CONTAINER_INHERIT

+
+public static final int FLAGS_CONTAINER_INHERIT
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_NO_PROPAGATE

+
+public static final int FLAGS_NO_PROPAGATE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_INHERIT_ONLY

+
+public static final int FLAGS_INHERIT_ONLY
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_INHERITED

+
+public static final int FLAGS_INHERITED
+
+
+
See Also:
Constant Field Values
+
+ + + + + + + + +
+Constructor Detail
+ +

+ACE

+
+public ACE()
+
+
+ + + + + + + + +
+Method Detail
+ +

+isAllow

+
+public boolean isAllow()
+
+
Returns true if this ACE is an allow ACE and false if it is a deny ACE. +

+

+
+
+
+
+ +

+isInherited

+
+public boolean isInherited()
+
+
Returns true if this ACE is an inherited ACE and false if it is a direct ACE. +

+ Note: For reasons not fully understood, FLAGS_INHERITED may + not be set within all security descriptors even though the ACE was in + face inherited. If an inherited ACE is added to a parent the Windows + ACL editor will rebuild all children ACEs and set this flag accordingly. +

+

+
+
+
+
+ +

+getFlags

+
+public int getFlags()
+
+
Returns the flags for this ACE. The isInherited() + method checks the FLAGS_INHERITED bit in these flags. +

+

+
+
+
+
+ +

+getApplyToText

+
+public java.lang.String getApplyToText()
+
+
Returns the 'Apply To' text for inheritance of ACEs on + directories such as 'This folder, subfolder and files'. For + files the text is always 'This object only'. +

+

+
+
+
+
+ +

+getAccessMask

+
+public int getAccessMask()
+
+
Returns the access mask accociated with this ACE. Use the + constants for FILE_READ_DATA, FILE_WRITE_DATA, + READ_CONTROL, GENERIC_ALL, etc with bitwise + operators to determine which bits of the mask are on or off. +

+

+
+
+
+
+ +

+getSID

+
+public SID getSID()
+
+
Return the SID associated with this ACE. +

+

+
+
+
+
+ +

+toString

+
+public java.lang.String toString()
+
+
Return a string represeting this ACE. +

+ Note: This function should probably be changed to return SDDL + fragments but currently it does not. +

+

+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/DosFileFilter.html b/docs/api/jcifs/smb/DosFileFilter.html new file mode 100644 index 0000000..c3dfaec --- /dev/null +++ b/docs/api/jcifs/smb/DosFileFilter.html @@ -0,0 +1,312 @@ + + + + + + +DosFileFilter (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class DosFileFilter

+
+java.lang.Object
+  extended byjcifs.smb.DosFileFilter
+
+
+
All Implemented Interfaces:
SmbFileFilter
+
+
+
+
public class DosFileFilter
extends java.lang.Object
implements SmbFileFilter
+ +

+


+ +

+ + + + + + + + + + + + + + + + + + +
+Field Summary
+protected  intattributes + +
+           
+protected  java.lang.Stringwildcard + +
+           
+  + + + + + + + + + + +
+Constructor Summary
DosFileFilter(java.lang.String wildcard, + int attributes) + +
+           
+  + + + + + + + + + + + +
+Method Summary
+ booleanaccept(SmbFile file) + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Field Detail
+ +

+wildcard

+
+protected java.lang.String wildcard
+
+
+
+
+
+ +

+attributes

+
+protected int attributes
+
+
+
+
+ + + + + + + + +
+Constructor Detail
+ +

+DosFileFilter

+
+public DosFileFilter(java.lang.String wildcard,
+                     int attributes)
+
+
+ + + + + + + + +
+Method Detail
+ +

+accept

+
+public boolean accept(SmbFile file)
+               throws SmbException
+
+
+
Specified by:
accept in interface SmbFileFilter
+
+
+ +
Throws: +
SmbException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/NtlmAuthenticator.html b/docs/api/jcifs/smb/NtlmAuthenticator.html new file mode 100644 index 0000000..1952d87 --- /dev/null +++ b/docs/api/jcifs/smb/NtlmAuthenticator.html @@ -0,0 +1,341 @@ + + + + + + +NtlmAuthenticator (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class NtlmAuthenticator

+
+java.lang.Object
+  extended byjcifs.smb.NtlmAuthenticator
+
+
+
+
public abstract class NtlmAuthenticator
extends java.lang.Object
+ +

+This class can be extended by applications that wish to trap authentication related exceptions and automatically retry the exceptional operation with different credentials. Read jCIFS Exceptions and NtlmAuthenticator for complete details. +

+ +

+


+ +

+ + + + + + + + + + + + + + + + +
+Constructor Summary
NtlmAuthenticator() + +
+           
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+protected  NtlmPasswordAuthenticationgetNtlmPasswordAuthentication() + +
+          An application extending this class must provide an implementation for this method that returns new user credentials try try when accessing SMB resources described by the getRequestingURL and getRequestingException methods.
+protected  SmbAuthExceptiongetRequestingException() + +
+           
+protected  java.lang.StringgetRequestingURL() + +
+           
+static NtlmPasswordAuthenticationrequestNtlmPasswordAuthentication(java.lang.String url, + SmbAuthException sae) + +
+          Used internally by jCIFS when an SmbAuthException is trapped to retrieve new user credentials.
+static voidsetDefault(NtlmAuthenticator a) + +
+          Set the default NtlmAuthenticator.
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+NtlmAuthenticator

+
+public NtlmAuthenticator()
+
+
+ + + + + + + + +
+Method Detail
+ +

+setDefault

+
+public static void setDefault(NtlmAuthenticator a)
+
+
Set the default NtlmAuthenticator. Once the default authenticator is set it cannot be changed. Calling this metho again will have no effect. +

+

+
+
+
+
+ +

+getRequestingURL

+
+protected final java.lang.String getRequestingURL()
+
+
+
+
+
+
+ +

+getRequestingException

+
+protected final SmbAuthException getRequestingException()
+
+
+
+
+
+
+ +

+requestNtlmPasswordAuthentication

+
+public static NtlmPasswordAuthentication requestNtlmPasswordAuthentication(java.lang.String url,
+                                                                           SmbAuthException sae)
+
+
Used internally by jCIFS when an SmbAuthException is trapped to retrieve new user credentials. +

+

+
+
+
+
+ +

+getNtlmPasswordAuthentication

+
+protected NtlmPasswordAuthentication getNtlmPasswordAuthentication()
+
+
An application extending this class must provide an implementation for this method that returns new user credentials try try when accessing SMB resources described by the getRequestingURL and getRequestingException methods. +If this method returns null the SmbAuthException that triggered the authenticator check will simply be rethrown. The default implementation returns null. +

+

+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/NtlmContext.html b/docs/api/jcifs/smb/NtlmContext.html new file mode 100644 index 0000000..1a2bb92 --- /dev/null +++ b/docs/api/jcifs/smb/NtlmContext.html @@ -0,0 +1,360 @@ + + + + + + +NtlmContext (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class NtlmContext

+
+java.lang.Object
+  extended byjcifs.smb.NtlmContext
+
+
+
+
public class NtlmContext
extends java.lang.Object
+ +

+For initiating NTLM authentication (including NTLMv2). If you want to add NTLMv2 authentication support to something this is what you want to use. See the code for details. Note that JCIFS does not implement the acceptor side of NTLM authentication. +

+ +

+


+ +

+ + + + + + + + + + + + + + + + +
+Constructor Summary
NtlmContext(NtlmPasswordAuthentication auth, + boolean doSigning) + +
+           
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ java.lang.StringgetNetbiosName() + +
+           
+ byte[]getServerChallenge() + +
+           
+ byte[]getSigningKey() + +
+           
+ byte[]initSecContext(byte[] token, + int offset, + int len) + +
+           
+ booleanisEstablished() + +
+           
+ java.lang.StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+NtlmContext

+
+public NtlmContext(NtlmPasswordAuthentication auth,
+                   boolean doSigning)
+
+
+ + + + + + + + +
+Method Detail
+ +

+toString

+
+public java.lang.String toString()
+
+
+
+
+
+
+ +

+isEstablished

+
+public boolean isEstablished()
+
+
+
+
+
+
+ +

+getServerChallenge

+
+public byte[] getServerChallenge()
+
+
+
+
+
+
+ +

+getSigningKey

+
+public byte[] getSigningKey()
+
+
+
+
+
+
+ +

+getNetbiosName

+
+public java.lang.String getNetbiosName()
+
+
+
+
+
+
+ +

+initSecContext

+
+public byte[] initSecContext(byte[] token,
+                             int offset,
+                             int len)
+                      throws SmbException
+
+
+ +
Throws: +
SmbException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/NtlmPasswordAuthentication.html b/docs/api/jcifs/smb/NtlmPasswordAuthentication.html new file mode 100644 index 0000000..d69621f --- /dev/null +++ b/docs/api/jcifs/smb/NtlmPasswordAuthentication.html @@ -0,0 +1,831 @@ + + + + + + +NtlmPasswordAuthentication (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class NtlmPasswordAuthentication

+
+java.lang.Object
+  extended byjcifs.smb.NtlmPasswordAuthentication
+
+
+
All Implemented Interfaces:
java.security.Principal, java.io.Serializable
+
+
+
+
public final class NtlmPasswordAuthentication
extends java.lang.Object
implements java.security.Principal, java.io.Serializable
+ +

+This class stores and encrypts NTLM user credentials. The default + credentials are retrieved from the jcifs.smb.client.domain, + jcifs.smb.client.username, and jcifs.smb.client.password + properties. +

+ Read jCIFS Exceptions and + NtlmAuthenticator for related information. +

+ +

+

+
See Also:
Serialized Form
+
+ +

+ + + + + + + + + + + + + + +
+Field Summary
+static NtlmPasswordAuthenticationANONYMOUS + +
+           
+  + + + + + + + + + + + + + + + + +
+Constructor Summary
NtlmPasswordAuthentication(java.lang.String userInfo) + +
+          Create an NtlmPasswordAuthentication object from the userinfo + component of an SMB URL like "domain;user:pass".
NtlmPasswordAuthentication(java.lang.String domain, + java.lang.String username, + byte[] challenge, + byte[] ansiHash, + byte[] unicodeHash) + +
+          Create an NtlmPasswordAuthentication object with raw password + hashes.
NtlmPasswordAuthentication(java.lang.String domain, + java.lang.String username, + java.lang.String password) + +
+          Create an NtlmPasswordAuthentication object from a + domain, username, and password.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanequals(java.lang.Object obj) + +
+          Compares two NtlmPasswordAuthentication objects for + equality.
+ byte[]getAnsiHash(byte[] challenge) + +
+          Computes the 24 byte ANSI password hash given the 8 byte server challenge.
+ java.lang.StringgetDomain() + +
+          Returns the domain.
+static byte[]getLMv2Response(byte[] responseKeyLM, + byte[] serverChallenge, + byte[] clientChallenge) + +
+           
+static byte[]getLMv2Response(java.lang.String domain, + java.lang.String user, + java.lang.String password, + byte[] challenge, + byte[] clientChallenge) + +
+          Creates the LMv2 response for the supplied information.
+ java.lang.StringgetName() + +
+          Return the domain and username in the format: + domain\\username.
+static byte[]getNTLM2Response(byte[] nTOWFv1, + byte[] serverChallenge, + byte[] clientChallenge) + +
+           
+static byte[]getNTLMResponse(java.lang.String password, + byte[] challenge) + +
+          Generate the Unicode MD4 hash for the password associated with these credentials.
+static byte[]getNTLMv2Response(byte[] responseKeyNT, + byte[] serverChallenge, + byte[] clientChallenge, + long nanos1601, + byte[] targetInfo) + +
+           
+ java.lang.StringgetPassword() + +
+          Returns the password in plain text or null if the raw password + hashes were used to construct this NtlmPasswordAuthentication + object which will be the case when NTLM HTTP Authentication is + used.
+static byte[]getPreNTLMResponse(java.lang.String password, + byte[] challenge) + +
+          Generate the ANSI DES hash for the password associated with these credentials.
+ byte[]getSigningKey(byte[] challenge) + +
+           
+ byte[]getUnicodeHash(byte[] challenge) + +
+          Computes the 24 byte Unicode password hash given the 8 byte server challenge.
+ java.lang.StringgetUsername() + +
+          Returns the username.
+ byte[]getUserSessionKey(byte[] challenge) + +
+          Returns the effective user session key.
+ inthashCode() + +
+          Return the upcased username hash code.
+static byte[]nTOWFv1(java.lang.String password) + +
+           
+static byte[]nTOWFv2(java.lang.String domain, + java.lang.String username, + java.lang.String password) + +
+           
+ java.lang.StringtoString() + +
+          Return the domain and username in the format: + domain\\username.
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Field Detail
+ +

+ANONYMOUS

+
+public static final NtlmPasswordAuthentication ANONYMOUS
+
+
+
+
+ + + + + + + + +
+Constructor Detail
+ +

+NtlmPasswordAuthentication

+
+public NtlmPasswordAuthentication(java.lang.String userInfo)
+
+
Create an NtlmPasswordAuthentication object from the userinfo + component of an SMB URL like "domain;user:pass". This constructor + is used internally be jCIFS when parsing SMB URLs. +

+

+
+ +

+NtlmPasswordAuthentication

+
+public NtlmPasswordAuthentication(java.lang.String domain,
+                                  java.lang.String username,
+                                  java.lang.String password)
+
+
Create an NtlmPasswordAuthentication object from a + domain, username, and password. Parameters that are null + will be substituted with jcifs.smb.client.domain, + jcifs.smb.client.username, jcifs.smb.client.password + property values. +

+

+
+ +

+NtlmPasswordAuthentication

+
+public NtlmPasswordAuthentication(java.lang.String domain,
+                                  java.lang.String username,
+                                  byte[] challenge,
+                                  byte[] ansiHash,
+                                  byte[] unicodeHash)
+
+
Create an NtlmPasswordAuthentication object with raw password + hashes. This is used exclusively by the jcifs.http.NtlmSsp + class which is in turn used by NTLM HTTP authentication functionality. +

+

+ + + + + + + + +
+Method Detail
+ +

+getPreNTLMResponse

+
+public static byte[] getPreNTLMResponse(java.lang.String password,
+                                        byte[] challenge)
+
+
Generate the ANSI DES hash for the password associated with these credentials. +

+

+
+
+
+
+
+
+
+ +

+getNTLMResponse

+
+public static byte[] getNTLMResponse(java.lang.String password,
+                                     byte[] challenge)
+
+
Generate the Unicode MD4 hash for the password associated with these credentials. +

+

+
+
+
+
+
+
+
+ +

+getLMv2Response

+
+public static byte[] getLMv2Response(java.lang.String domain,
+                                     java.lang.String user,
+                                     java.lang.String password,
+                                     byte[] challenge,
+                                     byte[] clientChallenge)
+
+
Creates the LMv2 response for the supplied information. +

+

+
+
+
+
Parameters:
domain - The domain in which the username exists.
user - The username.
password - The user's password.
challenge - The server challenge.
clientChallenge - The client challenge (nonce).
+
+
+
+ +

+getNTLM2Response

+
+public static byte[] getNTLM2Response(byte[] nTOWFv1,
+                                      byte[] serverChallenge,
+                                      byte[] clientChallenge)
+
+
+
+
+
+
+
+
+
+ +

+nTOWFv1

+
+public static byte[] nTOWFv1(java.lang.String password)
+
+
+
+
+
+
+
+
+
+ +

+nTOWFv2

+
+public static byte[] nTOWFv2(java.lang.String domain,
+                             java.lang.String username,
+                             java.lang.String password)
+
+
+
+
+
+
+
+
+
+ +

+getLMv2Response

+
+public static byte[] getLMv2Response(byte[] responseKeyLM,
+                                     byte[] serverChallenge,
+                                     byte[] clientChallenge)
+
+
+
+
+
+
+
+
+
+ +

+getNTLMv2Response

+
+public static byte[] getNTLMv2Response(byte[] responseKeyNT,
+                                       byte[] serverChallenge,
+                                       byte[] clientChallenge,
+                                       long nanos1601,
+                                       byte[] targetInfo)
+
+
+
+
+
+
+
+
+
+ +

+getDomain

+
+public java.lang.String getDomain()
+
+
Returns the domain. +

+

+
+
+
+
+
+
+
+ +

+getUsername

+
+public java.lang.String getUsername()
+
+
Returns the username. +

+

+
+
+
+
+
+
+
+ +

+getPassword

+
+public java.lang.String getPassword()
+
+
Returns the password in plain text or null if the raw password + hashes were used to construct this NtlmPasswordAuthentication + object which will be the case when NTLM HTTP Authentication is + used. There is no way to retrieve a users password in plain text unless + it is supplied by the user at runtime. +

+

+
+
+
+
+
+
+
+ +

+getName

+
+public java.lang.String getName()
+
+
Return the domain and username in the format: + domain\\username. This is equivalent to toString(). +

+

+
Specified by:
getName in interface java.security.Principal
+
+
+
+
+
+
+ +

+getAnsiHash

+
+public byte[] getAnsiHash(byte[] challenge)
+
+
Computes the 24 byte ANSI password hash given the 8 byte server challenge. +

+

+
+
+
+
+
+
+
+ +

+getUnicodeHash

+
+public byte[] getUnicodeHash(byte[] challenge)
+
+
Computes the 24 byte Unicode password hash given the 8 byte server challenge. +

+

+
+
+
+
+
+
+
+ +

+getSigningKey

+
+public byte[] getSigningKey(byte[] challenge)
+                     throws SmbException
+
+
+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+getUserSessionKey

+
+public byte[] getUserSessionKey(byte[] challenge)
+
+
Returns the effective user session key. +

+

+
+
+
+
Parameters:
challenge - The server challenge. +
Returns:
A byte[] containing the effective user session key, + used in SMB MAC signing and NTLMSSP signing and sealing.
+
+
+
+ +

+equals

+
+public boolean equals(java.lang.Object obj)
+
+
Compares two NtlmPasswordAuthentication objects for + equality. Two NtlmPasswordAuthentication objects are equal if + their caseless domain and username fields are equal and either both hashes are external and they are equal or both internally supplied passwords are equal. If one NtlmPasswordAuthentication object has external hashes (meaning negotiated via NTLM HTTP Authentication) and the other does not they will not be equal. This is technically not correct however the server 8 byte challage would be required to compute and compare the password hashes but that it not available with this method. +

+

+
Specified by:
equals in interface java.security.Principal
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
Return the upcased username hash code. +

+

+
Specified by:
hashCode in interface java.security.Principal
+
+
+
+
+
+
+ +

+toString

+
+public java.lang.String toString()
+
+
Return the domain and username in the format: + domain\\username. This is equivalent to getName(). +

+

+
Specified by:
toString in interface java.security.Principal
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SID.html b/docs/api/jcifs/smb/SID.html new file mode 100644 index 0000000..e1e70d1 --- /dev/null +++ b/docs/api/jcifs/smb/SID.html @@ -0,0 +1,986 @@ + + + + + + +SID (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class SID

+
+java.lang.Object
+  extended byjcifs.dcerpc.ndr.NdrObject
+      extended byjcifs.dcerpc.rpc.sid_t
+          extended byjcifs.smb.SID
+
+
+
+
public class SID
extends jcifs.dcerpc.rpc.sid_t
+ +

+A Windows SID is a numeric identifier used to represent Windows + accounts. SIDs are commonly represented using a textual format such as + S-1-5-21-1496946806-2192648263-3843101252-1029 but they may + also be resolved to yield the name of the associated Windows account + such as Administrators or MYDOM\alice. +

+ Consider the following output of examples/SidLookup.java: +

+        toString: S-1-5-21-4133388617-793952518-2001621813-512
+ toDisplayString: WNET\Domain Admins
+         getType: 2
+     getTypeText: Domain group
+   getDomainName: WNET
+  getAccountName: Domain Admins
+ 
+

+ +

+


+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Field Summary
+static SIDCREATOR_OWNER + +
+           
+static SIDEVERYONE + +
+           
+static intSID_FLAG_RESOLVE_SIDS + +
+           
+static intSID_TYPE_ALIAS + +
+           
+static intSID_TYPE_DELETED + +
+           
+static intSID_TYPE_DOM_GRP + +
+           
+static intSID_TYPE_DOMAIN + +
+           
+static intSID_TYPE_INVALID + +
+           
+static intSID_TYPE_UNKNOWN + +
+           
+static intSID_TYPE_USE_NONE + +
+           
+static intSID_TYPE_USER + +
+           
+static intSID_TYPE_WKN_GRP + +
+           
+static SIDSYSTEM + +
+           
+ + + + + + + +
Fields inherited from class jcifs.dcerpc.rpc.sid_t
identifier_authority, revision, sub_authority, sub_authority_count
+  + + + + + + + + + + + + + + + + + + + +
+Constructor Summary
SID(byte[] src, + int si) + +
+           
SID(jcifs.dcerpc.rpc.sid_t sid, + int type, + java.lang.String domainName, + java.lang.String acctName, + boolean decrementAuthority) + +
+           
SID(SID domsid, + int rid) + +
+          Construct a SID from a domain SID and an RID + (relative identifier).
SID(java.lang.String textual) + +
+          Construct a SID from it's textual representation such as + S-1-5-21-1496946806-2192648263-3843101252-1029.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanequals(java.lang.Object obj) + +
+           
+ java.lang.StringgetAccountName() + +
+          Return the sAMAccountName of this SID unless it could not + be resolved in which case the numeric RID is returned.
+ java.lang.StringgetDomainName() + +
+          Return the domain name of this SID unless it could not be + resolved in which case the numeric representation is returned.
+ SIDgetDomainSid() + +
+           
+ SID[]getGroupMemberSids(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth, + int flags) + +
+           
+ intgetRid() + +
+           
+static SIDgetServerSid(java.lang.String server, + NtlmPasswordAuthentication auth) + +
+           
+ intgetType() + +
+          Returns the type of this SID indicating the state or type of account.
+ java.lang.StringgetTypeText() + +
+          Return text represeting the SID type suitable for display to + users.
+ inthashCode() + +
+           
+ voidresolve(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth) + +
+          Manually resolve this SID.
+static voidresolveSids(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids) + +
+          Resolve an array of SIDs using a cache and at most one MSRPC request.
+static voidresolveSids(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids, + int offset, + int length) + +
+           
+static byte[]toByteArray(jcifs.dcerpc.rpc.sid_t sid) + +
+           
+ java.lang.StringtoDisplayString() + +
+          Return a String representing this SID ideal for display to + users.
+ java.lang.StringtoString() + +
+          Return the numeric representation of this sid such as + S-1-5-21-1496946806-2192648263-3843101252-1029.
+ + + + + + + +
Methods inherited from class jcifs.dcerpc.rpc.sid_t
decode, encode
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Field Detail
+ +

+SID_TYPE_USE_NONE

+
+public static final int SID_TYPE_USE_NONE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SID_TYPE_USER

+
+public static final int SID_TYPE_USER
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SID_TYPE_DOM_GRP

+
+public static final int SID_TYPE_DOM_GRP
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SID_TYPE_DOMAIN

+
+public static final int SID_TYPE_DOMAIN
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SID_TYPE_ALIAS

+
+public static final int SID_TYPE_ALIAS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SID_TYPE_WKN_GRP

+
+public static final int SID_TYPE_WKN_GRP
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SID_TYPE_DELETED

+
+public static final int SID_TYPE_DELETED
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SID_TYPE_INVALID

+
+public static final int SID_TYPE_INVALID
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SID_TYPE_UNKNOWN

+
+public static final int SID_TYPE_UNKNOWN
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SID_FLAG_RESOLVE_SIDS

+
+public static final int SID_FLAG_RESOLVE_SIDS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+EVERYONE

+
+public static SID EVERYONE
+
+
+
+
+
+ +

+CREATOR_OWNER

+
+public static SID CREATOR_OWNER
+
+
+
+
+
+ +

+SYSTEM

+
+public static SID SYSTEM
+
+
+
+
+ + + + + + + + +
+Constructor Detail
+ +

+SID

+
+public SID(byte[] src,
+           int si)
+
+
+
+ +

+SID

+
+public SID(java.lang.String textual)
+    throws SmbException
+
+
Construct a SID from it's textual representation such as + S-1-5-21-1496946806-2192648263-3843101252-1029. +

+

+
+ +

+SID

+
+public SID(SID domsid,
+           int rid)
+
+
Construct a SID from a domain SID and an RID + (relative identifier). For example, a domain SID + S-1-5-21-1496946806-2192648263-3843101252 and RID 1029 would + yield the SID S-1-5-21-1496946806-2192648263-3843101252-1029. +

+

+
+ +

+SID

+
+public SID(jcifs.dcerpc.rpc.sid_t sid,
+           int type,
+           java.lang.String domainName,
+           java.lang.String acctName,
+           boolean decrementAuthority)
+
+
+ + + + + + + + +
+Method Detail
+ +

+resolveSids

+
+public static void resolveSids(java.lang.String authorityServerName,
+                               NtlmPasswordAuthentication auth,
+                               SID[] sids,
+                               int offset,
+                               int length)
+                        throws java.io.IOException
+
+
+ +
Throws: +
java.io.IOException
+
+
+
+ +

+resolveSids

+
+public static void resolveSids(java.lang.String authorityServerName,
+                               NtlmPasswordAuthentication auth,
+                               SID[] sids)
+                        throws java.io.IOException
+
+
Resolve an array of SIDs using a cache and at most one MSRPC request. +

+ This method will attempt + to resolve SIDs using a cache and cache the results of any SIDs that + required resolving with the authority. SID cache entries are currently not + expired because under normal circumstances SID information never changes. +

+

+
Parameters:
authorityServerName - The hostname of the server that should be queried. For maximum efficiency this should be the hostname of a domain controller however a member server will work as well and a domain controller may not return names for SIDs corresponding to local accounts for which the domain controller is not an authority.
auth - The credentials that should be used to communicate with the named server. As usual, null indicates that default credentials should be used.
sids - The SIDs that should be resolved. After this function is called, the names associated with the SIDs may be queried with the toDisplayString, getDomainName, and getAccountName methods. +
Throws: +
java.io.IOException
+
+
+
+ +

+getServerSid

+
+public static SID getServerSid(java.lang.String server,
+                               NtlmPasswordAuthentication auth)
+                        throws java.io.IOException
+
+
+ +
Throws: +
java.io.IOException
+
+
+
+ +

+toByteArray

+
+public static byte[] toByteArray(jcifs.dcerpc.rpc.sid_t sid)
+
+
+
+
+
+
+ +

+getDomainSid

+
+public SID getDomainSid()
+
+
+
+
+
+
+ +

+getRid

+
+public int getRid()
+
+
+
+
+
+
+ +

+getType

+
+public int getType()
+
+
Returns the type of this SID indicating the state or type of account. +

+ SID types are described in the following table. + + + + + + + + + + + + +
TypeName
SID_TYPE_USE_NONE0
SID_TYPE_USERUser
SID_TYPE_DOM_GRPDomain group
SID_TYPE_DOMAINDomain
SID_TYPE_ALIASLocal group
SID_TYPE_WKN_GRPBuiltin group
SID_TYPE_DELETEDDeleted
SID_TYPE_INVALIDInvalid
SID_TYPE_UNKNOWNUnknown
+
+

+

+
+
+
+
+ +

+getTypeText

+
+public java.lang.String getTypeText()
+
+
Return text represeting the SID type suitable for display to + users. Text includes 'User', 'Domain group', 'Local group', etc. +

+

+
+
+
+
+ +

+getDomainName

+
+public java.lang.String getDomainName()
+
+
Return the domain name of this SID unless it could not be + resolved in which case the numeric representation is returned. +

+

+
+
+
+
+ +

+getAccountName

+
+public java.lang.String getAccountName()
+
+
Return the sAMAccountName of this SID unless it could not + be resolved in which case the numeric RID is returned. If this + SID is a domain SID, this method will return an empty String. +

+

+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
+
+
+
+ +

+equals

+
+public boolean equals(java.lang.Object obj)
+
+
+
+
+
+
+ +

+toString

+
+public java.lang.String toString()
+
+
Return the numeric representation of this sid such as + S-1-5-21-1496946806-2192648263-3843101252-1029. +

+

+
+
+
+
+ +

+toDisplayString

+
+public java.lang.String toDisplayString()
+
+
Return a String representing this SID ideal for display to + users. This method should return the same text that the ACL + editor in Windows would display. +

+ Specifically, if the SID has + been resolved and it is not a domain SID or builtin account, + the full DOMAIN\name form of the account will be + returned (e.g. MYDOM\alice or MYDOM\Domain Users). + If the SID has been resolved but it is is a domain SID, + only the domain name will be returned (e.g. MYDOM). + If the SID has been resolved but it is a builtin account, + only the name component will be returned (e.g. SYSTEM). + If the sid cannot be resolved the numeric representation from + toString() is returned. +

+

+
+
+
+
+ +

+resolve

+
+public void resolve(java.lang.String authorityServerName,
+                    NtlmPasswordAuthentication auth)
+             throws java.io.IOException
+
+
Manually resolve this SID. Normally SIDs are automatically + resolved. However, if a SID is constructed explicitly using a SID + constructor, JCIFS will have no knowledge of the server that created the + SID and therefore cannot possibly resolve it automatically. In this case, + this method will be necessary. +

+

+
Parameters:
authorityServerName - The FQDN of the server that is an authority for the SID.
auth - Credentials suitable for accessing the SID's information. +
Throws: +
java.io.IOException
+
+
+
+ +

+getGroupMemberSids

+
+public SID[] getGroupMemberSids(java.lang.String authorityServerName,
+                                NtlmPasswordAuthentication auth,
+                                int flags)
+                         throws java.io.IOException
+
+
+ +
Throws: +
java.io.IOException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SmbAuthException.html b/docs/api/jcifs/smb/SmbAuthException.html new file mode 100644 index 0000000..2425f4c --- /dev/null +++ b/docs/api/jcifs/smb/SmbAuthException.html @@ -0,0 +1,261 @@ + + + + + + +SmbAuthException (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class SmbAuthException

+
+java.lang.Object
+  extended byjava.lang.Throwable
+      extended byjava.lang.Exception
+          extended byjava.io.IOException
+              extended byjcifs.smb.SmbException
+                  extended byjcifs.smb.SmbAuthException
+
+
+
All Implemented Interfaces:
jcifs.smb.DosError, jcifs.smb.NtStatus, java.io.Serializable, jcifs.smb.WinError
+
+
+
+
public class SmbAuthException
extends SmbException
+ +

+The SmbAuthException encapsulates the variety of + authentication related error codes returned by an SMB server. +

+ See jCIFS Exceptions and NtlmAuthenticator for more information about SmbAuthException. +

+ +

+

+
See Also:
Serialized Form
+
+ +

+ + + + + + + + + + +
+Field Summary
+ + + + + + + +
Fields inherited from interface jcifs.smb.NtStatus
NT_STATUS_ACCESS_DENIED, NT_STATUS_ACCESS_VIOLATION, NT_STATUS_ACCOUNT_DISABLED, NT_STATUS_ACCOUNT_LOCKED_OUT, NT_STATUS_ACCOUNT_RESTRICTION, NT_STATUS_BAD_NETWORK_NAME, NT_STATUS_BUFFER_TOO_SMALL, NT_STATUS_CANNOT_DELETE, NT_STATUS_CANT_ACCESS_DOMAIN_INFO, NT_STATUS_CODES, NT_STATUS_DELETE_PENDING, NT_STATUS_DUPLICATE_NAME, NT_STATUS_FILE_IS_A_DIRECTORY, NT_STATUS_INSTANCE_NOT_AVAILABLE, NT_STATUS_INVALID_COMPUTER_NAME, NT_STATUS_INVALID_HANDLE, NT_STATUS_INVALID_INFO_CLASS, NT_STATUS_INVALID_LOGON_HOURS, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_PIPE_STATE, NT_STATUS_INVALID_SID, NT_STATUS_INVALID_WORKSTATION, NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED, NT_STATUS_LOGON_FAILURE, NT_STATUS_LOGON_TYPE_NOT_GRANTED, NT_STATUS_MESSAGES, NT_STATUS_MORE_PROCESSING_REQUIRED, NT_STATUS_NETWORK_ACCESS_DENIED, NT_STATUS_NETWORK_NAME_DELETED, NT_STATUS_NO_LOGON_SERVERS, NT_STATUS_NO_SUCH_ALIAS, NT_STATUS_NO_SUCH_DEVICE, NT_STATUS_NO_SUCH_DOMAIN, NT_STATUS_NO_SUCH_FILE, NT_STATUS_NO_SUCH_USER, NT_STATUS_NO_TRUST_SAM_ACCOUNT, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT, NT_STATUS_NONE_MAPPED, NT_STATUS_NOT_A_DIRECTORY, NT_STATUS_NOT_FOUND, NT_STATUS_NOT_IMPLEMENTED, NT_STATUS_OBJECT_NAME_COLLISION, NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_OBJECT_NAME_NOT_FOUND, NT_STATUS_OBJECT_PATH_INVALID, NT_STATUS_OBJECT_PATH_NOT_FOUND, NT_STATUS_OBJECT_PATH_SYNTAX_BAD, NT_STATUS_OK, NT_STATUS_PASSWORD_EXPIRED, NT_STATUS_PASSWORD_MUST_CHANGE, NT_STATUS_PATH_NOT_COVERED, NT_STATUS_PIPE_BROKEN, NT_STATUS_PIPE_BUSY, NT_STATUS_PIPE_CLOSING, NT_STATUS_PIPE_DISCONNECTED, NT_STATUS_PIPE_LISTENING, NT_STATUS_PIPE_NOT_AVAILABLE, NT_STATUS_PORT_DISCONNECTED, NT_STATUS_REQUEST_NOT_ACCEPTED, NT_STATUS_SHARING_VIOLATION, NT_STATUS_TRUSTED_DOMAIN_FAILURE, NT_STATUS_UNSUCCESSFUL, NT_STATUS_USER_EXISTS, NT_STATUS_WRONG_PASSWORD
+ + + + + + + +
Fields inherited from interface jcifs.smb.DosError
DOS_ERROR_CODES, DOS_ERROR_MESSAGES
+ + + + + + + +
Fields inherited from interface jcifs.smb.WinError
ERROR_ACCESS_DENIED, ERROR_BAD_PIPE, ERROR_MORE_DATA, ERROR_NO_BROWSER_SERVERS_FOUND, ERROR_NO_DATA, ERROR_PIPE_BUSY, ERROR_PIPE_NOT_CONNECTED, ERROR_REQ_NOT_ACCEP, ERROR_SUCCESS, WINERR_CODES, WINERR_MESSAGES
+  + + + + + + + + + + + + + +
Methods inherited from class jcifs.smb.SmbException
getNtStatus, getRootCause, toString
+ + + + + + + +
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + + + +


+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SmbException.html b/docs/api/jcifs/smb/SmbException.html new file mode 100644 index 0000000..2327442 --- /dev/null +++ b/docs/api/jcifs/smb/SmbException.html @@ -0,0 +1,369 @@ + + + + + + +SmbException (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class SmbException

+
+java.lang.Object
+  extended byjava.lang.Throwable
+      extended byjava.lang.Exception
+          extended byjava.io.IOException
+              extended byjcifs.smb.SmbException
+
+
+
All Implemented Interfaces:
jcifs.smb.DosError, jcifs.smb.NtStatus, java.io.Serializable, jcifs.smb.WinError
+
+
+
Direct Known Subclasses:
SmbAuthException
+
+
+
+
public class SmbException
extends java.io.IOException
implements jcifs.smb.NtStatus, jcifs.smb.DosError, jcifs.smb.WinError
+ +

+There are hundreds of error codes that may be returned by a CIFS + server. Rather than represent each with it's own Exception + class, this class represents all of them. For many of the popular + error codes, constants and text messages like "The device is not ready" + are provided. +

+ The jCIFS client maps DOS error codes to NTSTATUS codes. This means that + the user may recieve a different error from a legacy server than that of + a newer varient such as Windows NT and above. If you should encounter + such a case, please report it to jcifs at samba dot org and we will + change the mapping. +

+ +

+

+
See Also:
Serialized Form
+
+ +

+ + + + + + + + + + +
+Field Summary
+ + + + + + + +
Fields inherited from interface jcifs.smb.NtStatus
NT_STATUS_ACCESS_DENIED, NT_STATUS_ACCESS_VIOLATION, NT_STATUS_ACCOUNT_DISABLED, NT_STATUS_ACCOUNT_LOCKED_OUT, NT_STATUS_ACCOUNT_RESTRICTION, NT_STATUS_BAD_NETWORK_NAME, NT_STATUS_BUFFER_TOO_SMALL, NT_STATUS_CANNOT_DELETE, NT_STATUS_CANT_ACCESS_DOMAIN_INFO, NT_STATUS_CODES, NT_STATUS_DELETE_PENDING, NT_STATUS_DUPLICATE_NAME, NT_STATUS_FILE_IS_A_DIRECTORY, NT_STATUS_INSTANCE_NOT_AVAILABLE, NT_STATUS_INVALID_COMPUTER_NAME, NT_STATUS_INVALID_HANDLE, NT_STATUS_INVALID_INFO_CLASS, NT_STATUS_INVALID_LOGON_HOURS, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_PIPE_STATE, NT_STATUS_INVALID_SID, NT_STATUS_INVALID_WORKSTATION, NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED, NT_STATUS_LOGON_FAILURE, NT_STATUS_LOGON_TYPE_NOT_GRANTED, NT_STATUS_MESSAGES, NT_STATUS_MORE_PROCESSING_REQUIRED, NT_STATUS_NETWORK_ACCESS_DENIED, NT_STATUS_NETWORK_NAME_DELETED, NT_STATUS_NO_LOGON_SERVERS, NT_STATUS_NO_SUCH_ALIAS, NT_STATUS_NO_SUCH_DEVICE, NT_STATUS_NO_SUCH_DOMAIN, NT_STATUS_NO_SUCH_FILE, NT_STATUS_NO_SUCH_USER, NT_STATUS_NO_TRUST_SAM_ACCOUNT, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT, NT_STATUS_NONE_MAPPED, NT_STATUS_NOT_A_DIRECTORY, NT_STATUS_NOT_FOUND, NT_STATUS_NOT_IMPLEMENTED, NT_STATUS_OBJECT_NAME_COLLISION, NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_OBJECT_NAME_NOT_FOUND, NT_STATUS_OBJECT_PATH_INVALID, NT_STATUS_OBJECT_PATH_NOT_FOUND, NT_STATUS_OBJECT_PATH_SYNTAX_BAD, NT_STATUS_OK, NT_STATUS_PASSWORD_EXPIRED, NT_STATUS_PASSWORD_MUST_CHANGE, NT_STATUS_PATH_NOT_COVERED, NT_STATUS_PIPE_BROKEN, NT_STATUS_PIPE_BUSY, NT_STATUS_PIPE_CLOSING, NT_STATUS_PIPE_DISCONNECTED, NT_STATUS_PIPE_LISTENING, NT_STATUS_PIPE_NOT_AVAILABLE, NT_STATUS_PORT_DISCONNECTED, NT_STATUS_REQUEST_NOT_ACCEPTED, NT_STATUS_SHARING_VIOLATION, NT_STATUS_TRUSTED_DOMAIN_FAILURE, NT_STATUS_UNSUCCESSFUL, NT_STATUS_USER_EXISTS, NT_STATUS_WRONG_PASSWORD
+ + + + + + + +
Fields inherited from interface jcifs.smb.DosError
DOS_ERROR_CODES, DOS_ERROR_MESSAGES
+ + + + + + + +
Fields inherited from interface jcifs.smb.WinError
ERROR_ACCESS_DENIED, ERROR_BAD_PIPE, ERROR_MORE_DATA, ERROR_NO_BROWSER_SERVERS_FOUND, ERROR_NO_DATA, ERROR_PIPE_BUSY, ERROR_PIPE_NOT_CONNECTED, ERROR_REQ_NOT_ACCEP, ERROR_SUCCESS, WINERR_CODES, WINERR_MESSAGES
+  + + + + + + + + + + +
+Constructor Summary
SmbException(int errcode, + boolean winerr) + +
+           
+  + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ intgetNtStatus() + +
+           
+ java.lang.ThrowablegetRootCause() + +
+           
+ java.lang.StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+SmbException

+
+public SmbException(int errcode,
+                    boolean winerr)
+
+
+ + + + + + + + +
+Method Detail
+ +

+getNtStatus

+
+public int getNtStatus()
+
+
+
+
+
+
+
+
+
+ +

+getRootCause

+
+public java.lang.Throwable getRootCause()
+
+
+
+
+
+
+
+
+
+ +

+toString

+
+public java.lang.String toString()
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SmbFile.html b/docs/api/jcifs/smb/SmbFile.html new file mode 100644 index 0000000..5a76b24 --- /dev/null +++ b/docs/api/jcifs/smb/SmbFile.html @@ -0,0 +1,4669 @@ + + + + + + +SmbFile (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class SmbFile

+
+java.lang.Object
+  extended byjava.net.URLConnection
+      extended byjcifs.smb.SmbFile
+
+
+
All Implemented Interfaces:
jcifs.smb.SmbConstants
+
+
+
Direct Known Subclasses:
SmbNamedPipe
+
+
+
+
public class SmbFile
extends java.net.URLConnection
implements jcifs.smb.SmbConstants
+ +

+This class represents a resource on an SMB network. Mainly these + resources are files and directories however an SmbFile + may also refer to servers and workgroups. If the resource is a file or + directory the methods of SmbFile follow the behavior of + the well known File class. One fundamental difference + is the usage of a URL scheme [1] to specify the target file or + directory. SmbFile URLs have the following syntax: + +

+     smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?[param=value[param2=value2[...]]]
+ 
+ + This example: + +
+     smb://storage15/public/foo.txt
+ 
+ + would reference the file foo.txt in the share + public on the server storage15. In addition + to referencing files and directories, jCIFS can also address servers, + and workgroups. +

+ Important: all SMB URLs that represent + workgroups, servers, shares, or directories require a trailing slash '/'. + +

+ When using the java.net.URL class with + 'smb://' URLs it is necessary to first call the static + jcifs.Config.registerSmbURLHandler(); method. This is required + to register the SMB protocol handler. +

+ The userinfo component of the SMB URL (domain;user:pass) must + be URL encoded if it contains reserved characters. According to RFC 2396 + these characters are non US-ASCII characters and most meta characters + however jCIFS will work correctly with anything but '@' which is used + to delimit the userinfo component from the server and '%' which is the + URL escape character itself. +

+ The server + component may a traditional NetBIOS name, a DNS name, or IP + address. These name resolution mechanisms and their resolution order + can be changed (See Setting Name + Resolution Properties). The servername and path components are + not case sensitive but the domain, username, and password components + are. It is also likely that properties must be specified for jcifs + to function (See Setting + JCIFS Properties). Here are some examples of SMB URLs with brief + descriptions of what they do: + +

[1] This URL scheme is based largely on the SMB + Filesharing URL Scheme IETF draft. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SMB URL Examples
URLDescription
smb://users-nyc;miallen:mypass@angus/tmp/ + This URL references a share called tmp on the server + angus as user miallen who's password is + mypass. +
+ smb://Administrator:P%40ss@msmith1/c/WINDOWS/Desktop/foo.txt + A relativly sophisticated example that references a file + msmith1's desktop as user Administrator. Notice the '@' is URL encoded with the '%40' hexcode escape. +
smb://angus/ + This references only a server. The behavior of some methods is different + in this context(e.g. you cannot delete a server) however + as you might expect the list method will list the available + shares on this server. +
smb://myworkgroup/ + This syntactically is identical to the above example. However if + myworkgroup happends to be a workgroup(which is indeed + suggested by the name) the list method will return + a list of servers that have registered themselves as members of + myworkgroup. +
smb:// + Just as smb://server/ lists shares and + smb://workgroup/ lists servers, the smb:// + URL lists all available workgroups on a netbios LAN. Again, + in this context many methods are not valid and return default + values(e.g. isHidden will always return false). +
smb://angus.foo.net/d/jcifs/pipes.doc + The server name may also be a DNS name as it is in this example. See + Setting Name Resolution Properties + for details. +
smb://192.168.1.15/ADMIN$/ + The server name may also be an IP address. See Setting Name Resolution Properties + for details. +
+ smb://domain;username:password@server/share/path/to/file.txt + A prototypical example that uses all the fields. +
smb://myworkgroup/angus/ <-- ILLEGAL + Despite the hierarchial relationship between workgroups, servers, and + filesystems this example is not valid. +
+ smb://server/share/path/to/dir <-- ILLEGAL + URLs that represent workgroups, servers, shares, or directories require a trailing slash '/'. +
+ smb://MYGROUP/?SERVER=192.168.10.15 + SMB URLs support some query string parameters. In this example + the SERVER parameter is used to override the + server name service lookup to contact the server 192.168.10.15 + (presumably known to be a master + browser) for the server list in workgroup MYGROUP. +
+ +

A second constructor argument may be specified to augment the URL + for better programmatic control when processing many files under + a common base. This is slightly different from the corresponding + java.io.File usage; a '/' at the beginning of the second + parameter will still use the server component of the first parameter. The + examples below illustrate the resulting URLs when this second contructor + argument is used. + +

+ + + + + + + + + + + + + + + + + + + + + + +
+ Examples Of SMB URLs When Augmented With A Second Constructor Parameter
+ First ParameterSecond ParameterResult
+ smb://host/share/a/b/ + + c/d/ + + smb://host/share/a/b/c/d/ +
+ smb://host/share/foo/bar/ + + /share2/zig/zag + + smb://host/share2/zig/zag +
+ smb://host/share/foo/bar/ + + ../zip/ + + smb://host/share/foo/zip/ +
+ smb://host/share/zig/zag + + smb://foo/bar/ + + smb://foo/bar/ +
+ smb://host/share/foo/ + + ../.././.././../foo/ + + smb://host/foo/ +
+ smb://host/share/zig/zag + + / + + smb://host/ +
+ smb://server/ + + ../ + + smb://server/ +
+ smb:// + + myworkgroup/ + + smb://myworkgroup/ +
+ smb://myworkgroup/ + + angus/ + + smb://myworkgroup/angus/ <-- ILLEGAL
(But if you first create an SmbFile with 'smb://workgroup/' and use and use it as the first parameter to a constructor that accepts it with a second String parameter jCIFS will factor out the 'workgroup'.) +
+ +

Instances of the SmbFile class are immutable; that is, + once created, the abstract pathname represented by an SmbFile object + will never change. +

+ +

+

+
See Also:
File
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Field Summary
+static intATTR_ARCHIVE + +
+          A file with this bit on as returned by getAttributes() or set + with setAttributes() is an archived file
+static intATTR_DIRECTORY + +
+          A file with this bit on as returned by getAttributes() is + a directory
+static intATTR_HIDDEN + +
+          A file with this bit on as returned by getAttributes() or set + with setAttributes() will be hidden
+static intATTR_READONLY + +
+          A file with this bit on as returned by getAttributes() or set + with setAttributes() will be read-only
+static intATTR_SYSTEM + +
+          A file with this bit on as returned by getAttributes() or set + with setAttributes() will be a system file
+static intATTR_VOLUME + +
+          A file with this bit on as returned by getAttributes() is + a volume
+static intCAP_DFS + +
+           
+static intCAP_EXTENDED_SECURITY + +
+           
+static intCAP_LARGE_FILES + +
+           
+static intCAP_LEVEL_II_OPLOCKS + +
+           
+static intCAP_LOCK_AND_READ + +
+           
+static intCAP_MPX_MODE + +
+           
+static intCAP_NONE + +
+           
+static intCAP_NT_FIND + +
+           
+static intCAP_NT_SMBS + +
+           
+static intCAP_RAW_MODE + +
+           
+static intCAP_RPC_REMOTE_APIS + +
+           
+static intCAP_STATUS32 + +
+           
+static intCAP_UNICODE + +
+           
+static intCAPABILITIES + +
+           
+static intCMD_OFFSET + +
+           
+static java.util.LinkedListCONNECTIONS + +
+           
+static intDEFAULT_CAPABILITIES + +
+           
+static intDEFAULT_FLAGS2 + +
+           
+static intDEFAULT_MAX_MPX_COUNT + +
+           
+static intDEFAULT_PORT + +
+           
+static intDEFAULT_RCV_BUF_SIZE + +
+           
+static intDEFAULT_RESPONSE_TIMEOUT + +
+           
+static intDEFAULT_SND_BUF_SIZE + +
+           
+static intDEFAULT_SO_TIMEOUT + +
+           
+static intDEFAULT_SSN_LIMIT + +
+           
+static intDELETE + +
+           
+protected static jcifs.smb.Dfsdfs + +
+           
+static intERROR_CODE_OFFSET + +
+           
+static intFILE_APPEND_DATA + +
+           
+static intFILE_DELETE + +
+           
+static intFILE_EXECUTE + +
+           
+static intFILE_NO_SHARE + +
+          When specified as the shareAccess constructor parameter, + other SMB clients (including other threads making calls into jCIFS) + will not be permitted to access the target file and will receive "The + file is being accessed by another process" message.
+static intFILE_READ_ATTRIBUTES + +
+           
+static intFILE_READ_DATA + +
+           
+static intFILE_READ_EA + +
+           
+static intFILE_SHARE_DELETE + +
+          When specified as the shareAccess constructor parameter, + other SMB clients will be permitted to delete the target file while + this file is open.
+static intFILE_SHARE_READ + +
+          When specified as the shareAccess constructor parameter, + other SMB clients will be permitted to read from the target file while + this file is open.
+static intFILE_SHARE_WRITE + +
+          When specified as the shareAccess constructor parameter, + other SMB clients will be permitted to write to the target file while + this file is open.
+static intFILE_WRITE_ATTRIBUTES + +
+           
+static intFILE_WRITE_DATA + +
+           
+static intFILE_WRITE_EA + +
+           
+static intFLAGS_COPY_SOURCE_MODE_ASCII + +
+           
+static intFLAGS_COPY_TARGET_MODE_ASCII + +
+           
+static intFLAGS_LOCK_AND_READ_WRITE_AND_UNLOCK + +
+           
+static intFLAGS_NONE + +
+           
+static intFLAGS_NOTIFY_OF_MODIFY_ACTION + +
+           
+static intFLAGS_OFFSET + +
+           
+static intFLAGS_OPLOCK_REQUESTED_OR_GRANTED + +
+           
+static intFLAGS_PATH_NAMES_CANONICALIZED + +
+           
+static intFLAGS_PATH_NAMES_CASELESS + +
+           
+static intFLAGS_RECEIVE_BUFFER_POSTED + +
+           
+static intFLAGS_RESPONSE + +
+           
+static intFLAGS_TARGET_MUST_BE_DIRECTORY + +
+           
+static intFLAGS_TARGET_MUST_BE_FILE + +
+           
+static intFLAGS_TREE_COPY + +
+           
+static intFLAGS_VERIFY_ALL_WRITES + +
+           
+static intFLAGS2 + +
+           
+static intFLAGS2_EXTENDED_ATTRIBUTES + +
+           
+static intFLAGS2_EXTENDED_SECURITY_NEGOTIATION + +
+           
+static intFLAGS2_LONG_FILENAMES + +
+           
+static intFLAGS2_NONE + +
+           
+static intFLAGS2_PERMIT_READ_IF_EXECUTE_PERM + +
+           
+static intFLAGS2_RESOLVE_PATHS_IN_DFS + +
+           
+static intFLAGS2_SECURITY_SIGNATURES + +
+           
+static intFLAGS2_STATUS32 + +
+           
+static intFLAGS2_UNICODE + +
+           
+static booleanFORCE_UNICODE + +
+           
+static intGENERIC_ALL + +
+           
+static intGENERIC_EXECUTE + +
+           
+static intGENERIC_READ + +
+           
+static intGENERIC_WRITE + +
+           
+static intHEADER_LENGTH + +
+           
+static java.net.InetAddressLADDR + +
+           
+static intLM_COMPATIBILITY + +
+           
+static intLPORT + +
+           
+static intMAX_MPX_COUNT + +
+           
+static longMILLISECONDS_BETWEEN_1970_AND_1601 + +
+           
+static java.lang.StringNATIVE_LANMAN + +
+           
+static java.lang.StringNATIVE_OS + +
+           
+static java.lang.StringNETBIOS_HOSTNAME + +
+           
+static jcifs.smb.SmbTransportNULL_TRANSPORT + +
+           
+static java.lang.StringOEM_ENCODING + +
+           
+static intOPEN_FUNCTION_FAIL_IF_EXISTS + +
+           
+static intOPEN_FUNCTION_OVERWRITE_IF_EXISTS + +
+           
+static intPID + +
+           
+static intRCV_BUF_SIZE + +
+           
+static intREAD_CONTROL + +
+           
+static intRESPONSE_TIMEOUT + +
+           
+static intSECURITY_SHARE + +
+           
+static intSECURITY_USER + +
+           
+static intSIGNATURE_OFFSET + +
+           
+static booleanSIGNPREF + +
+           
+static intSND_BUF_SIZE + +
+           
+static intSO_TIMEOUT + +
+           
+static intSSN_LIMIT + +
+           
+static intSYNCHRONIZE + +
+           
+static booleanTCP_NODELAY + +
+           
+static intTID_OFFSET + +
+           
+static intTYPE_COMM + +
+          Returned by getType() if the resource this SmbFile + represents is a communications device.
+static intTYPE_FILESYSTEM + +
+          Returned by getType() if the resource this SmbFile + represents is a regular file or directory.
+static intTYPE_NAMED_PIPE + +
+          Returned by getType() if the resource this SmbFile + represents is a named pipe.
+static intTYPE_PRINTER + +
+          Returned by getType() if the resource this SmbFile + represents is a printer.
+static intTYPE_SERVER + +
+          Returned by getType() if the resource this SmbFile + represents is a server.
+static intTYPE_SHARE + +
+          Returned by getType() if the resource this SmbFile + represents is a share.
+static intTYPE_WORKGROUP + +
+          Returned by getType() if the resource this SmbFile + represents is a workgroup.
+static java.util.TimeZoneTZ + +
+           
+static java.lang.StringUNI_ENCODING + +
+           
+static booleanUSE_BATCHING + +
+           
+static booleanUSE_EXTSEC + +
+           
+static booleanUSE_NTSMBS + +
+           
+static booleanUSE_NTSTATUS + +
+           
+static booleanUSE_UNICODE + +
+           
+static intVC_NUMBER + +
+           
+static intWRITE_DAC + +
+           
+static intWRITE_OWNER + +
+           
+ + + + + + + +
Fields inherited from class java.net.URLConnection
allowUserInteraction, connected, doInput, doOutput, ifModifiedSince, url, useCaches
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Constructor Summary
SmbFile(SmbFile context, + java.lang.String name) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(SmbFile context, + java.lang.String name, + int shareAccess) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(java.lang.String url) + +
+          Constructs an SmbFile representing a resource on an SMB network such as + a file or directory.
SmbFile(java.lang.String url, + NtlmPasswordAuthentication auth) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(java.lang.String url, + NtlmPasswordAuthentication auth, + int shareAccess) + +
+          Constructs an SmbFile representing a file on an SMB network.
SmbFile(java.lang.String context, + java.lang.String name) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(java.lang.String context, + java.lang.String name, + NtlmPasswordAuthentication auth) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(java.lang.String context, + java.lang.String name, + NtlmPasswordAuthentication auth, + int shareAccess) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(java.net.URL url) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory from a URL object.
SmbFile(java.net.URL url, + NtlmPasswordAuthentication auth) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory from a URL object and an + NtlmPasswordAuthentication object.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleancanRead() + +
+          Tests to see if the file this SmbFile represents can be + read.
+ booleancanWrite() + +
+          Tests to see if the file this SmbFile represents + exists and is not marked read-only.
+ voidconnect() + +
+          It is not necessary to call this method directly.
+ voidcopyTo(SmbFile dest) + +
+          This method will copy the file or directory represented by this + SmbFile and it's sub-contents to the location specified by the + dest parameter.
+ voidcreateNewFile() + +
+          Create a new file but fail if it already exists.
+ longcreateTime() + +
+          Retrieve the time this SmbFile was created.
+ voiddelete() + +
+          This method will delete the file or directory specified by this + SmbFile.
+ booleanequals(java.lang.Object obj) + +
+          Tests to see if two SmbFile objects are equal.
+ booleanexists() + +
+          Tests to see if the SMB resource exists.
+ intgetAttributes() + +
+          Return the attributes of this file.
+ java.lang.StringgetCanonicalPath() + +
+          Returns the full URL of this SMB resource with '.' and '..' components + factored out.
+ intgetContentLength() + +
+          This URLConnection method just returns the result of length().
+ longgetDate() + +
+          This URLConnection method just returns the result of lastModified.
+ java.lang.StringgetDfsPath() + +
+          If the path of this SmbFile falls within a DFS volume, + this method will return the referral path to which it maps.
+ longgetDiskFreeSpace() + +
+          This method returns the free disk space in bytes of the drive this share + represents or the drive on which the directory or file resides.
+ java.io.InputStreamgetInputStream() + +
+          This URLConnection method just returns a new SmbFileInputStream created with this file.
+ longgetLastModified() + +
+          This URLConnection method just returns the result of lastModified.
+ java.lang.StringgetName() + +
+          Returns the last component of the target URL.
+ java.io.OutputStreamgetOutputStream() + +
+          This URLConnection method just returns a new SmbFileOutputStream created with this file.
+ java.lang.StringgetParent() + +
+          Everything but the last component of the URL representing this SMB + resource is effectivly it's parent.
+ java.lang.StringgetPath() + +
+          Returns the full uncanonicalized URL of this SMB resource.
+ java.security.PrincipalgetPrincipal() + +
+          Returns the NtlmPasswordAuthentication object used as + credentials with this file or pipe.
+ ACE[]getSecurity() + +
+          Return an array of Access Control Entry (ACE) objects representing + the security descriptor associated with this file or directory.
+ ACE[]getSecurity(boolean resolveSids) + +
+          Return an array of Access Control Entry (ACE) objects representing + the security descriptor associated with this file or directory.
+ java.lang.StringgetServer() + +
+          Retrieve the hostname of the server for this SMB resource.
+ java.lang.StringgetShare() + +
+          Retrieves the share associated with this SMB resource.
+ ACE[]getShareSecurity(boolean resolveSids) + +
+          Return an array of Access Control Entry (ACE) objects representing + the share permissions on the share exporting this file or directory.
+ intgetType() + +
+          Returns type of of object this SmbFile represents.
+ java.lang.StringgetUncPath() + +
+          Retuns the Windows UNC style path with backslashs intead of forward slashes.
+ inthashCode() + +
+          Computes a hashCode for this file based on the URL string and IP + address if the server.
+ booleanisDirectory() + +
+          Tests to see if the file this SmbFile represents is a directory.
+ booleanisFile() + +
+          Tests to see if the file this SmbFile represents is not a directory.
+ booleanisHidden() + +
+          Tests to see if the file this SmbFile represents is marked as + hidden.
+ longlastModified() + +
+          Retrieve the last time the file represented by this + SmbFile was modified.
+ longlength() + +
+          Returns the length of this SmbFile in bytes.
+ java.lang.String[]list() + +
+          List the contents of this SMB resource.
+ java.lang.String[]list(SmbFilenameFilter filter) + +
+          List the contents of this SMB resource.
+ SmbFile[]listFiles() + +
+          List the contents of this SMB resource as an array of + SmbFile objects.
+ SmbFile[]listFiles(SmbFileFilter filter) + +
+          List the contents of this SMB resource.
+ SmbFile[]listFiles(SmbFilenameFilter filter) + +
+          List the contents of this SMB resource.
+ SmbFile[]listFiles(java.lang.String wildcard) + +
+          The CIFS protocol provides for DOS "wildcards" to be used as + a performance enhancement.
+ voidmkdir() + +
+          Creates a directory with the path specified by this + SmbFile.
+ voidmkdirs() + +
+          Creates a directory with the path specified by this SmbFile + and any parent directories that do not exist.
+protected  booleanpathNamesPossiblyEqual(java.lang.String path1, + java.lang.String path2) + +
+           
+ voidrenameTo(SmbFile dest) + +
+          Changes the name of the file this SmbFile represents to the name + designated by the SmbFile argument.
+ voidsetAttributes(int attrs) + +
+          Set the attributes of this file.
+ voidsetCreateTime(long time) + +
+          Set the create time of the file.
+ voidsetLastModified(long time) + +
+          Set the last modified time of the file.
+ voidsetReadOnly() + +
+          Make this file read-only.
+ voidsetReadWrite() + +
+          Turn off the read-only attribute of this file.
+ java.lang.StringtoString() + +
+          Returns the string representation of this SmbFile object.
+ java.net.URLtoURL() + +
+          Deprecated. Use getURL() instead
+ + + + + + + +
Methods inherited from class java.net.URLConnection
addRequestProperty, getAllowUserInteraction, getContent, getContent, getContentEncoding, getContentType, getDefaultAllowUserInteraction, getDefaultRequestProperty, getDefaultUseCaches, getDoInput, getDoOutput, getExpiration, getFileNameMap, getHeaderField, getHeaderField, getHeaderFieldDate, getHeaderFieldInt, getHeaderFieldKey, getHeaderFields, getIfModifiedSince, getPermission, getRequestProperties, getRequestProperty, getURL, getUseCaches, guessContentTypeFromName, guessContentTypeFromStream, setAllowUserInteraction, setContentHandlerFactory, setDefaultAllowUserInteraction, setDefaultRequestProperty, setDefaultUseCaches, setDoInput, setDoOutput, setFileNameMap, setIfModifiedSince, setRequestProperty, setUseCaches
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Field Detail
+ +

+FILE_NO_SHARE

+
+public static final int FILE_NO_SHARE
+
+
When specified as the shareAccess constructor parameter, + other SMB clients (including other threads making calls into jCIFS) + will not be permitted to access the target file and will receive "The + file is being accessed by another process" message. +

+

+
See Also:
Constant Field Values
+
+
+ +

+FILE_SHARE_READ

+
+public static final int FILE_SHARE_READ
+
+
When specified as the shareAccess constructor parameter, + other SMB clients will be permitted to read from the target file while + this file is open. This constant may be logically OR'd with other share + access flags. +

+

+
See Also:
Constant Field Values
+
+
+ +

+FILE_SHARE_WRITE

+
+public static final int FILE_SHARE_WRITE
+
+
When specified as the shareAccess constructor parameter, + other SMB clients will be permitted to write to the target file while + this file is open. This constant may be logically OR'd with other share + access flags. +

+

+
See Also:
Constant Field Values
+
+
+ +

+FILE_SHARE_DELETE

+
+public static final int FILE_SHARE_DELETE
+
+
When specified as the shareAccess constructor parameter, + other SMB clients will be permitted to delete the target file while + this file is open. This constant may be logically OR'd with other share + access flags. +

+

+
See Also:
Constant Field Values
+
+
+ +

+ATTR_READONLY

+
+public static final int ATTR_READONLY
+
+
A file with this bit on as returned by getAttributes() or set + with setAttributes() will be read-only +

+

+
See Also:
Constant Field Values
+
+
+ +

+ATTR_HIDDEN

+
+public static final int ATTR_HIDDEN
+
+
A file with this bit on as returned by getAttributes() or set + with setAttributes() will be hidden +

+

+
See Also:
Constant Field Values
+
+
+ +

+ATTR_SYSTEM

+
+public static final int ATTR_SYSTEM
+
+
A file with this bit on as returned by getAttributes() or set + with setAttributes() will be a system file +

+

+
See Also:
Constant Field Values
+
+
+ +

+ATTR_VOLUME

+
+public static final int ATTR_VOLUME
+
+
A file with this bit on as returned by getAttributes() is + a volume +

+

+
See Also:
Constant Field Values
+
+
+ +

+ATTR_DIRECTORY

+
+public static final int ATTR_DIRECTORY
+
+
A file with this bit on as returned by getAttributes() is + a directory +

+

+
See Also:
Constant Field Values
+
+
+ +

+ATTR_ARCHIVE

+
+public static final int ATTR_ARCHIVE
+
+
A file with this bit on as returned by getAttributes() or set + with setAttributes() is an archived file +

+

+
See Also:
Constant Field Values
+
+
+ +

+TYPE_FILESYSTEM

+
+public static final int TYPE_FILESYSTEM
+
+
Returned by getType() if the resource this SmbFile + represents is a regular file or directory. +

+

+
See Also:
Constant Field Values
+
+
+ +

+TYPE_WORKGROUP

+
+public static final int TYPE_WORKGROUP
+
+
Returned by getType() if the resource this SmbFile + represents is a workgroup. +

+

+
See Also:
Constant Field Values
+
+
+ +

+TYPE_SERVER

+
+public static final int TYPE_SERVER
+
+
Returned by getType() if the resource this SmbFile + represents is a server. +

+

+
See Also:
Constant Field Values
+
+
+ +

+TYPE_SHARE

+
+public static final int TYPE_SHARE
+
+
Returned by getType() if the resource this SmbFile + represents is a share. +

+

+
See Also:
Constant Field Values
+
+
+ +

+TYPE_NAMED_PIPE

+
+public static final int TYPE_NAMED_PIPE
+
+
Returned by getType() if the resource this SmbFile + represents is a named pipe. +

+

+
See Also:
Constant Field Values
+
+
+ +

+TYPE_PRINTER

+
+public static final int TYPE_PRINTER
+
+
Returned by getType() if the resource this SmbFile + represents is a printer. +

+

+
See Also:
Constant Field Values
+
+
+ +

+TYPE_COMM

+
+public static final int TYPE_COMM
+
+
Returned by getType() if the resource this SmbFile + represents is a communications device. +

+

+
See Also:
Constant Field Values
+
+
+ +

+dfs

+
+protected static jcifs.smb.Dfs dfs
+
+
+
+
+
+ +

+DEFAULT_PORT

+
+public static final int DEFAULT_PORT
+
+
+
See Also:
Constant Field Values
+
+
+ +

+DEFAULT_MAX_MPX_COUNT

+
+public static final int DEFAULT_MAX_MPX_COUNT
+
+
+
See Also:
Constant Field Values
+
+
+ +

+DEFAULT_RESPONSE_TIMEOUT

+
+public static final int DEFAULT_RESPONSE_TIMEOUT
+
+
+
See Also:
Constant Field Values
+
+
+ +

+DEFAULT_SO_TIMEOUT

+
+public static final int DEFAULT_SO_TIMEOUT
+
+
+
See Also:
Constant Field Values
+
+
+ +

+DEFAULT_RCV_BUF_SIZE

+
+public static final int DEFAULT_RCV_BUF_SIZE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+DEFAULT_SND_BUF_SIZE

+
+public static final int DEFAULT_SND_BUF_SIZE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+DEFAULT_SSN_LIMIT

+
+public static final int DEFAULT_SSN_LIMIT
+
+
+
See Also:
Constant Field Values
+
+
+ +

+LADDR

+
+public static final java.net.InetAddress LADDR
+
+
+
+
+
+ +

+LPORT

+
+public static final int LPORT
+
+
+
+
+
+ +

+MAX_MPX_COUNT

+
+public static final int MAX_MPX_COUNT
+
+
+
+
+
+ +

+SND_BUF_SIZE

+
+public static final int SND_BUF_SIZE
+
+
+
+
+
+ +

+RCV_BUF_SIZE

+
+public static final int RCV_BUF_SIZE
+
+
+
+
+
+ +

+USE_UNICODE

+
+public static final boolean USE_UNICODE
+
+
+
+
+
+ +

+FORCE_UNICODE

+
+public static final boolean FORCE_UNICODE
+
+
+
+
+
+ +

+USE_NTSTATUS

+
+public static final boolean USE_NTSTATUS
+
+
+
+
+
+ +

+SIGNPREF

+
+public static final boolean SIGNPREF
+
+
+
+
+
+ +

+USE_NTSMBS

+
+public static final boolean USE_NTSMBS
+
+
+
+
+
+ +

+USE_EXTSEC

+
+public static final boolean USE_EXTSEC
+
+
+
+
+
+ +

+NETBIOS_HOSTNAME

+
+public static final java.lang.String NETBIOS_HOSTNAME
+
+
+
+
+
+ +

+LM_COMPATIBILITY

+
+public static final int LM_COMPATIBILITY
+
+
+
+
+
+ +

+FLAGS_NONE

+
+public static final int FLAGS_NONE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_LOCK_AND_READ_WRITE_AND_UNLOCK

+
+public static final int FLAGS_LOCK_AND_READ_WRITE_AND_UNLOCK
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_RECEIVE_BUFFER_POSTED

+
+public static final int FLAGS_RECEIVE_BUFFER_POSTED
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_PATH_NAMES_CASELESS

+
+public static final int FLAGS_PATH_NAMES_CASELESS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_PATH_NAMES_CANONICALIZED

+
+public static final int FLAGS_PATH_NAMES_CANONICALIZED
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_OPLOCK_REQUESTED_OR_GRANTED

+
+public static final int FLAGS_OPLOCK_REQUESTED_OR_GRANTED
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_NOTIFY_OF_MODIFY_ACTION

+
+public static final int FLAGS_NOTIFY_OF_MODIFY_ACTION
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_RESPONSE

+
+public static final int FLAGS_RESPONSE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS2_NONE

+
+public static final int FLAGS2_NONE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS2_LONG_FILENAMES

+
+public static final int FLAGS2_LONG_FILENAMES
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS2_EXTENDED_ATTRIBUTES

+
+public static final int FLAGS2_EXTENDED_ATTRIBUTES
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS2_SECURITY_SIGNATURES

+
+public static final int FLAGS2_SECURITY_SIGNATURES
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS2_EXTENDED_SECURITY_NEGOTIATION

+
+public static final int FLAGS2_EXTENDED_SECURITY_NEGOTIATION
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS2_RESOLVE_PATHS_IN_DFS

+
+public static final int FLAGS2_RESOLVE_PATHS_IN_DFS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS2_PERMIT_READ_IF_EXECUTE_PERM

+
+public static final int FLAGS2_PERMIT_READ_IF_EXECUTE_PERM
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS2_STATUS32

+
+public static final int FLAGS2_STATUS32
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS2_UNICODE

+
+public static final int FLAGS2_UNICODE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_NONE

+
+public static final int CAP_NONE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_RAW_MODE

+
+public static final int CAP_RAW_MODE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_MPX_MODE

+
+public static final int CAP_MPX_MODE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_UNICODE

+
+public static final int CAP_UNICODE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_LARGE_FILES

+
+public static final int CAP_LARGE_FILES
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_NT_SMBS

+
+public static final int CAP_NT_SMBS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_RPC_REMOTE_APIS

+
+public static final int CAP_RPC_REMOTE_APIS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_STATUS32

+
+public static final int CAP_STATUS32
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_LEVEL_II_OPLOCKS

+
+public static final int CAP_LEVEL_II_OPLOCKS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_LOCK_AND_READ

+
+public static final int CAP_LOCK_AND_READ
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_NT_FIND

+
+public static final int CAP_NT_FIND
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_DFS

+
+public static final int CAP_DFS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CAP_EXTENDED_SECURITY

+
+public static final int CAP_EXTENDED_SECURITY
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_READ_DATA

+
+public static final int FILE_READ_DATA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_WRITE_DATA

+
+public static final int FILE_WRITE_DATA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_APPEND_DATA

+
+public static final int FILE_APPEND_DATA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_READ_EA

+
+public static final int FILE_READ_EA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_WRITE_EA

+
+public static final int FILE_WRITE_EA
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_EXECUTE

+
+public static final int FILE_EXECUTE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_DELETE

+
+public static final int FILE_DELETE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_READ_ATTRIBUTES

+
+public static final int FILE_READ_ATTRIBUTES
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FILE_WRITE_ATTRIBUTES

+
+public static final int FILE_WRITE_ATTRIBUTES
+
+
+
See Also:
Constant Field Values
+
+
+ +

+DELETE

+
+public static final int DELETE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+READ_CONTROL

+
+public static final int READ_CONTROL
+
+
+
See Also:
Constant Field Values
+
+
+ +

+WRITE_DAC

+
+public static final int WRITE_DAC
+
+
+
See Also:
Constant Field Values
+
+
+ +

+WRITE_OWNER

+
+public static final int WRITE_OWNER
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SYNCHRONIZE

+
+public static final int SYNCHRONIZE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+GENERIC_ALL

+
+public static final int GENERIC_ALL
+
+
+
See Also:
Constant Field Values
+
+
+ +

+GENERIC_EXECUTE

+
+public static final int GENERIC_EXECUTE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+GENERIC_WRITE

+
+public static final int GENERIC_WRITE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+GENERIC_READ

+
+public static final int GENERIC_READ
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_TARGET_MUST_BE_FILE

+
+public static final int FLAGS_TARGET_MUST_BE_FILE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_TARGET_MUST_BE_DIRECTORY

+
+public static final int FLAGS_TARGET_MUST_BE_DIRECTORY
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_COPY_TARGET_MODE_ASCII

+
+public static final int FLAGS_COPY_TARGET_MODE_ASCII
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_COPY_SOURCE_MODE_ASCII

+
+public static final int FLAGS_COPY_SOURCE_MODE_ASCII
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_VERIFY_ALL_WRITES

+
+public static final int FLAGS_VERIFY_ALL_WRITES
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_TREE_COPY

+
+public static final int FLAGS_TREE_COPY
+
+
+
See Also:
Constant Field Values
+
+
+ +

+OPEN_FUNCTION_FAIL_IF_EXISTS

+
+public static final int OPEN_FUNCTION_FAIL_IF_EXISTS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+OPEN_FUNCTION_OVERWRITE_IF_EXISTS

+
+public static final int OPEN_FUNCTION_OVERWRITE_IF_EXISTS
+
+
+
See Also:
Constant Field Values
+
+
+ +

+PID

+
+public static final int PID
+
+
+
+
+
+ +

+SECURITY_SHARE

+
+public static final int SECURITY_SHARE
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SECURITY_USER

+
+public static final int SECURITY_USER
+
+
+
See Also:
Constant Field Values
+
+
+ +

+CMD_OFFSET

+
+public static final int CMD_OFFSET
+
+
+
See Also:
Constant Field Values
+
+
+ +

+ERROR_CODE_OFFSET

+
+public static final int ERROR_CODE_OFFSET
+
+
+
See Also:
Constant Field Values
+
+
+ +

+FLAGS_OFFSET

+
+public static final int FLAGS_OFFSET
+
+
+
See Also:
Constant Field Values
+
+
+ +

+SIGNATURE_OFFSET

+
+public static final int SIGNATURE_OFFSET
+
+
+
See Also:
Constant Field Values
+
+
+ +

+TID_OFFSET

+
+public static final int TID_OFFSET
+
+
+
See Also:
Constant Field Values
+
+
+ +

+HEADER_LENGTH

+
+public static final int HEADER_LENGTH
+
+
+
See Also:
Constant Field Values
+
+
+ +

+MILLISECONDS_BETWEEN_1970_AND_1601

+
+public static final long MILLISECONDS_BETWEEN_1970_AND_1601
+
+
+
See Also:
Constant Field Values
+
+
+ +

+TZ

+
+public static final java.util.TimeZone TZ
+
+
+
+
+
+ +

+USE_BATCHING

+
+public static final boolean USE_BATCHING
+
+
+
+
+
+ +

+OEM_ENCODING

+
+public static final java.lang.String OEM_ENCODING
+
+
+
+
+
+ +

+UNI_ENCODING

+
+public static final java.lang.String UNI_ENCODING
+
+
+
See Also:
Constant Field Values
+
+
+ +

+DEFAULT_FLAGS2

+
+public static final int DEFAULT_FLAGS2
+
+
+
+
+
+ +

+DEFAULT_CAPABILITIES

+
+public static final int DEFAULT_CAPABILITIES
+
+
+
+
+
+ +

+FLAGS2

+
+public static final int FLAGS2
+
+
+
+
+
+ +

+CAPABILITIES

+
+public static final int CAPABILITIES
+
+
+
+
+
+ +

+TCP_NODELAY

+
+public static final boolean TCP_NODELAY
+
+
+
+
+
+ +

+RESPONSE_TIMEOUT

+
+public static final int RESPONSE_TIMEOUT
+
+
+
+
+
+ +

+CONNECTIONS

+
+public static final java.util.LinkedList CONNECTIONS
+
+
+
+
+
+ +

+SSN_LIMIT

+
+public static final int SSN_LIMIT
+
+
+
+
+
+ +

+SO_TIMEOUT

+
+public static final int SO_TIMEOUT
+
+
+
+
+
+ +

+NATIVE_OS

+
+public static final java.lang.String NATIVE_OS
+
+
+
+
+
+ +

+NATIVE_LANMAN

+
+public static final java.lang.String NATIVE_LANMAN
+
+
+
+
+
+ +

+VC_NUMBER

+
+public static final int VC_NUMBER
+
+
+
See Also:
Constant Field Values
+
+
+ +

+NULL_TRANSPORT

+
+public static final jcifs.smb.SmbTransport NULL_TRANSPORT
+
+
+
+
+ + + + + + + + +
+Constructor Detail
+ +

+SmbFile

+
+public SmbFile(java.lang.String url)
+        throws java.net.MalformedURLException
+
+
Constructs an SmbFile representing a resource on an SMB network such as + a file or directory. See the description and examples of smb URLs above. +

+

Parameters:
url - A URL string +
Throws: +
java.net.MalformedURLException - If the parent and child parameters + do not follow the prescribed syntax
+
+ +

+SmbFile

+
+public SmbFile(SmbFile context,
+               java.lang.String name)
+        throws java.net.MalformedURLException,
+               java.net.UnknownHostException
+
+
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. The second parameter is a relative path from + the parent SmbFile. See the description above for examples + of using the second name parameter. +

+

Parameters:
context - A base SmbFile
name - A path string relative to the parent paremeter +
Throws: +
java.net.MalformedURLException - If the parent and child parameters + do not follow the prescribed syntax +
java.net.UnknownHostException - If the server or workgroup of the context file cannot be determined
+
+ +

+SmbFile

+
+public SmbFile(java.lang.String context,
+               java.lang.String name)
+        throws java.net.MalformedURLException
+
+
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. The second parameter is a relative path from + the parent. See the description above for examples of + using the second chile parameter. +

+

Parameters:
context - A URL string
name - A path string relative to the context paremeter +
Throws: +
java.net.MalformedURLException - If the context and name parameters + do not follow the prescribed syntax
+
+ +

+SmbFile

+
+public SmbFile(java.lang.String url,
+               NtlmPasswordAuthentication auth)
+        throws java.net.MalformedURLException
+
+
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. +

+

Parameters:
url - A URL string
auth - The credentials the client should use for authentication +
Throws: +
java.net.MalformedURLException - If the url parameter does not follow the prescribed syntax
+
+ +

+SmbFile

+
+public SmbFile(java.lang.String url,
+               NtlmPasswordAuthentication auth,
+               int shareAccess)
+        throws java.net.MalformedURLException
+
+
Constructs an SmbFile representing a file on an SMB network. The + shareAccess parameter controls what permissions other + clients have when trying to access the same file while this instance + is still open. This value is either FILE_NO_SHARE or any + combination of FILE_SHARE_READ, FILE_SHARE_WRITE, + and FILE_SHARE_DELETE logically OR'd together. +

+

Parameters:
url - A URL string
auth - The credentials the client should use for authentication
shareAccess - Specifies what access other clients have while this file is open. +
Throws: +
java.net.MalformedURLException - If the url parameter does not follow the prescribed syntax
+
+ +

+SmbFile

+
+public SmbFile(java.lang.String context,
+               java.lang.String name,
+               NtlmPasswordAuthentication auth)
+        throws java.net.MalformedURLException
+
+
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. The second parameter is a relative path from + the context. See the description above for examples of + using the second name parameter. +

+

Parameters:
context - A URL string
name - A path string relative to the context paremeter
auth - The credentials the client should use for authentication +
Throws: +
java.net.MalformedURLException - If the context and name parameters + do not follow the prescribed syntax
+
+ +

+SmbFile

+
+public SmbFile(java.lang.String context,
+               java.lang.String name,
+               NtlmPasswordAuthentication auth,
+               int shareAccess)
+        throws java.net.MalformedURLException
+
+
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. The second parameter is a relative path from + the context. See the description above for examples of + using the second name parameter. The shareAccess + parameter controls what permissions other clients have when trying + to access the same file while this instance is still open. This + value is either FILE_NO_SHARE or any combination + of FILE_SHARE_READ, FILE_SHARE_WRITE, and + FILE_SHARE_DELETE logically OR'd together. +

+

Parameters:
context - A URL string
name - A path string relative to the context paremeter
auth - The credentials the client should use for authentication
shareAccess - Specifies what access other clients have while this file is open. +
Throws: +
java.net.MalformedURLException - If the context and name parameters + do not follow the prescribed syntax
+
+ +

+SmbFile

+
+public SmbFile(SmbFile context,
+               java.lang.String name,
+               int shareAccess)
+        throws java.net.MalformedURLException,
+               java.net.UnknownHostException
+
+
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory. The second parameter is a relative path from + the context. See the description above for examples of + using the second name parameter. The shareAccess + parameter controls what permissions other clients have when trying + to access the same file while this instance is still open. This + value is either FILE_NO_SHARE or any combination + of FILE_SHARE_READ, FILE_SHARE_WRITE, and + FILE_SHARE_DELETE logically OR'd together. +

+

Parameters:
context - A base SmbFile
name - A path string relative to the context file path
shareAccess - Specifies what access other clients have while this file is open. +
Throws: +
java.net.MalformedURLException - If the context and name parameters + do not follow the prescribed syntax +
java.net.UnknownHostException
+
+ +

+SmbFile

+
+public SmbFile(java.net.URL url)
+
+
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory from a URL object. +

+

Parameters:
url - The URL of the target resource
+
+ +

+SmbFile

+
+public SmbFile(java.net.URL url,
+               NtlmPasswordAuthentication auth)
+
+
Constructs an SmbFile representing a resource on an SMB network such + as a file or directory from a URL object and an + NtlmPasswordAuthentication object. +

+

Parameters:
url - The URL of the target resource
auth - The credentials the client should use for authentication
+ + + + + + + + +
+Method Detail
+ +

+connect

+
+public void connect()
+             throws java.io.IOException
+
+
It is not necessary to call this method directly. This is the + URLConnection implementation of connect(). +

+

+
+
+
+ +
Throws: +
java.io.IOException
+
+
+
+ +

+getPrincipal

+
+public java.security.Principal getPrincipal()
+
+
Returns the NtlmPasswordAuthentication object used as + credentials with this file or pipe. This can be used to retrieve the + username for example: + + String username = f.getPrincipal().getName(); + + The Principal object returned will never be null + however the username can be null indication anonymous + credentials were used (e.g. some IPC$ services). +

+

+
+
+
+
+
+
+
+ +

+getName

+
+public java.lang.String getName()
+
+
Returns the last component of the target URL. This will + effectively be the name of the file or directory represented by this + SmbFile or in the case of URLs that only specify a server + or workgroup, the server or workgroup will be returned. The name of + the root URL smb:// is also smb://. If this + SmbFile refers to a workgroup, server, share, or directory, + the name will include a trailing slash '/' so that composing new + SmbFiles will maintain the trailing slash requirement. +

+

+
+
+
+ +
Returns:
The last component of the URL associated with this SMB + resource or smb:// if the resource is smb:// + itself.
+
+
+
+ +

+getParent

+
+public java.lang.String getParent()
+
+
Everything but the last component of the URL representing this SMB + resource is effectivly it's parent. The root URL smb:// + does not have a parent. In this case smb:// is returned. +

+

+
+
+
+ +
Returns:
The parent directory of this SMB resource or + smb:// if the resource refers to the root of the URL + hierarchy which incedentally is also smb://.
+
+
+
+ +

+getPath

+
+public java.lang.String getPath()
+
+
Returns the full uncanonicalized URL of this SMB resource. An + SmbFile constructed with the result of this method will + result in an SmbFile that is equal to the original. +

+

+
+
+
+ +
Returns:
The uncanonicalized full URL of this SMB resource.
+
+
+
+ +

+getUncPath

+
+public java.lang.String getUncPath()
+
+
Retuns the Windows UNC style path with backslashs intead of forward slashes. +

+

+
+
+
+ +
Returns:
The UNC path.
+
+
+
+ +

+getCanonicalPath

+
+public java.lang.String getCanonicalPath()
+
+
Returns the full URL of this SMB resource with '.' and '..' components + factored out. An SmbFile constructed with the result of + this method will result in an SmbFile that is equal to + the original. +

+

+
+
+
+ +
Returns:
The canonicalized URL of this SMB resource.
+
+
+
+ +

+getShare

+
+public java.lang.String getShare()
+
+
Retrieves the share associated with this SMB resource. In + the case of smb://, smb://workgroup/, + and smb://server/ URLs which do not specify a share, + null will be returned. +

+

+
+
+
+ +
Returns:
The share component or null if there is no share
+
+
+
+ +

+getServer

+
+public java.lang.String getServer()
+
+
Retrieve the hostname of the server for this SMB resource. If this + SmbFile references a workgroup, the name of the workgroup + is returned. If this SmbFile refers to the root of this + SMB network hierarchy, null is returned. +

+

+
+
+
+ +
Returns:
The server or workgroup name or null if this + SmbFile refers to the root smb:// resource.
+
+
+
+ +

+getType

+
+public int getType()
+            throws SmbException
+
+
Returns type of of object this SmbFile represents. +

+

+
+
+
+ +
Returns:
TYPE_FILESYSTEM, TYPE_WORKGROUP, TYPE_SERVER, TYPE_SHARE, + TYPE_PRINTER, TYPE_NAMED_PIPE, or TYPE_COMM. +
Throws: +
SmbException
+
+
+
+ +

+exists

+
+public boolean exists()
+               throws SmbException
+
+
Tests to see if the SMB resource exists. If the resource refers + only to a server, this method determines if the server exists on the + network and is advertising SMB services. If this resource refers to + a workgroup, this method determines if the workgroup name is valid on + the local SMB network. If this SmbFile refers to the root + smb:// resource true is always returned. If + this SmbFile is a traditional file or directory, it will + be queried for on the specified server as expected. +

+

+
+
+
+ +
Returns:
true if the resource exists or is alive or + false otherwise +
Throws: +
SmbException
+
+
+
+ +

+canRead

+
+public boolean canRead()
+                throws SmbException
+
+
Tests to see if the file this SmbFile represents can be + read. Because any file, directory, or other resource can be read if it + exists, this method simply calls the exists method. +

+

+
+
+
+ +
Returns:
true if the file is read-only +
Throws: +
SmbException
+
+
+
+ +

+canWrite

+
+public boolean canWrite()
+                 throws SmbException
+
+
Tests to see if the file this SmbFile represents + exists and is not marked read-only. By default, resources are + considered to be read-only and therefore for smb://, + smb://workgroup/, and smb://server/ resources + will be read-only. +

+

+
+
+
+ +
Returns:
true if the resource exists is not marked + read-only +
Throws: +
SmbException
+
+
+
+ +

+isDirectory

+
+public boolean isDirectory()
+                    throws SmbException
+
+
Tests to see if the file this SmbFile represents is a directory. +

+

+
+
+
+ +
Returns:
true if this SmbFile is a directory +
Throws: +
SmbException
+
+
+
+ +

+isFile

+
+public boolean isFile()
+               throws SmbException
+
+
Tests to see if the file this SmbFile represents is not a directory. +

+

+
+
+
+ +
Returns:
true if this SmbFile is not a directory +
Throws: +
SmbException
+
+
+
+ +

+isHidden

+
+public boolean isHidden()
+                 throws SmbException
+
+
Tests to see if the file this SmbFile represents is marked as + hidden. This method will also return true for shares with names that + end with '$' such as IPC$ or C$. +

+

+
+
+
+ +
Returns:
true if the SmbFile is marked as being hidden +
Throws: +
SmbException
+
+
+
+ +

+getDfsPath

+
+public java.lang.String getDfsPath()
+                            throws SmbException
+
+
If the path of this SmbFile falls within a DFS volume, + this method will return the referral path to which it maps. Otherwise + null is returned. +

+

+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+createTime

+
+public long createTime()
+                throws SmbException
+
+
Retrieve the time this SmbFile was created. The value + returned is suitable for constructing a Date object + (i.e. seconds since Epoch 1970). Times should be the same as those + reported using the properties dialog of the Windows Explorer program. + + For Win95/98/Me this is actually the last write time. It is currently + not possible to retrieve the create time from files on these systems. +

+

+
+
+
+ +
Returns:
The number of milliseconds since the 00:00:00 GMT, January 1, + 1970 as a long value +
Throws: +
SmbException
+
+
+
+ +

+lastModified

+
+public long lastModified()
+                  throws SmbException
+
+
Retrieve the last time the file represented by this + SmbFile was modified. The value returned is suitable for + constructing a Date object (i.e. seconds since Epoch + 1970). Times should be the same as those reported using the properties + dialog of the Windows Explorer program. +

+

+
+
+
+ +
Returns:
The number of milliseconds since the 00:00:00 GMT, January 1, + 1970 as a long value +
Throws: +
SmbException
+
+
+
+ +

+list

+
+public java.lang.String[] list()
+                        throws SmbException
+
+
List the contents of this SMB resource. The list returned by this + method will be; + +
    +
  • files and directories contained within this resource if the + resource is a normal disk file directory, +
  • all available NetBIOS workgroups or domains if this resource is + the top level URL smb://, +
  • all servers registered as members of a NetBIOS workgroup if this + resource refers to a workgroup in a smb://workgroup/ URL, +
  • all browseable shares of a server including printers, IPC + services, or disk volumes if this resource is a server URL in the form + smb://server/, +
  • or null if the resource cannot be resolved. +
+

+

+
+
+
+ +
Returns:
A String[] array of files and directories, + workgroups, servers, or shares depending on the context of the + resource URL +
Throws: +
SmbException
+
+
+
+ +

+list

+
+public java.lang.String[] list(SmbFilenameFilter filter)
+                        throws SmbException
+
+
List the contents of this SMB resource. The list returned will be + identical to the list returned by the parameterless list() + method minus filenames filtered by the specified filter. +

+

+
+
+
+
Parameters:
filter - a filename filter to exclude filenames from the results +
Throws: +
SmbException - # @return An array of filenames
+
+
+
+ +

+listFiles

+
+public SmbFile[] listFiles()
+                    throws SmbException
+
+
List the contents of this SMB resource as an array of + SmbFile objects. This method is much more efficient than + the regular list method when querying attributes of each + file in the result set. +

+ The list of SmbFiles returned by this method will be; + +

    +
  • files and directories contained within this resource if the + resource is a normal disk file directory, +
  • all available NetBIOS workgroups or domains if this resource is + the top level URL smb://, +
  • all servers registered as members of a NetBIOS workgroup if this + resource refers to a workgroup in a smb://workgroup/ URL, +
  • all browseable shares of a server including printers, IPC + services, or disk volumes if this resource is a server URL in the form + smb://server/, +
  • or null if the resource cannot be resolved. +
+

+

+
+
+
+ +
Returns:
An array of SmbFile objects representing file + and directories, workgroups, servers, or shares depending on the context + of the resource URL +
Throws: +
SmbException
+
+
+
+ +

+listFiles

+
+public SmbFile[] listFiles(java.lang.String wildcard)
+                    throws SmbException
+
+
The CIFS protocol provides for DOS "wildcards" to be used as + a performance enhancement. The client does not have to filter + the names and the server does not have to return all directory + entries. +

+ The wildcard expression may consist of two special meta + characters in addition to the normal filename characters. The '*' + character matches any number of characters in part of a name. If + the expression begins with one or more '?'s then exactly that + many characters will be matched whereas if it ends with '?'s + it will match that many characters or less. +

+ Wildcard expressions will not filter workgroup names or server names. + +

+ winnt> ls c?o*
+ clock.avi                  -rw--      82944 Mon Oct 14 1996 1:38 AM
+ Cookies                    drw--          0 Fri Nov 13 1998 9:42 PM
+ 2 items in 5ms
+ 
+

+

+
+
+
+
Parameters:
wildcard - a wildcard expression +
Returns:
An array of SmbFile objects representing file + and directories, workgroups, servers, or shares depending on the context + of the resource URL +
Throws: +
SmbException
+
+
+
+ +

+listFiles

+
+public SmbFile[] listFiles(SmbFilenameFilter filter)
+                    throws SmbException
+
+
List the contents of this SMB resource. The list returned will be + identical to the list returned by the parameterless listFiles() + method minus files filtered by the specified filename filter. +

+

+
+
+
+
Parameters:
filter - a filter to exclude files from the results +
Returns:
An array of SmbFile objects +
Throws: +
SmbException
+
+
+
+ +

+listFiles

+
+public SmbFile[] listFiles(SmbFileFilter filter)
+                    throws SmbException
+
+
List the contents of this SMB resource. The list returned will be + identical to the list returned by the parameterless listFiles() + method minus filenames filtered by the specified filter. +

+

+
+
+
+
Parameters:
filter - a file filter to exclude files from the results +
Returns:
An array of SmbFile objects +
Throws: +
SmbException
+
+
+
+ +

+renameTo

+
+public void renameTo(SmbFile dest)
+              throws SmbException
+
+
Changes the name of the file this SmbFile represents to the name + designated by the SmbFile argument. +

+ Remember: SmbFiles are immutible and therefore + the path associated with this SmbFile object will not + change). To access the renamed file it is necessary to construct a + new SmbFile. +

+

+
+
+
+
Parameters:
dest - An SmbFile that represents the new pathname +
Throws: +
java.lang.NullPointerException - If the dest argument is null +
SmbException
+
+
+
+ +

+copyTo

+
+public void copyTo(SmbFile dest)
+            throws SmbException
+
+
This method will copy the file or directory represented by this + SmbFile and it's sub-contents to the location specified by the + dest parameter. This file and the destination file do not + need to be on the same host. This operation does not copy extended + file attibutes such as ACLs but it does copy regular attributes as + well as create and last write times. This method is almost twice as + efficient as manually copying as it employs an additional write + thread to read and write data concurrently. +

+ It is not possible (nor meaningful) to copy entire workgroups or + servers. +

+

+
+
+
+
Parameters:
dest - the destination file or directory +
Throws: +
SmbException
+
+
+
+ +

+delete

+
+public void delete()
+            throws SmbException
+
+
This method will delete the file or directory specified by this + SmbFile. If the target is a directory, the contents of + the directory will be deleted as well. If a file within the directory or + it's sub-directories is marked read-only, the read-only status will + be removed and the file will be deleted. +

+

+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+length

+
+public long length()
+            throws SmbException
+
+
Returns the length of this SmbFile in bytes. If this object + is a TYPE_SHARE the total capacity of the disk shared in + bytes is returned. If this object is a directory or a type other than + TYPE_SHARE, 0L is returned. +

+

+
+
+
+ +
Returns:
The length of the file in bytes or 0 if this + SmbFile is not a file. +
Throws: +
SmbException
+
+
+
+ +

+getDiskFreeSpace

+
+public long getDiskFreeSpace()
+                      throws SmbException
+
+
This method returns the free disk space in bytes of the drive this share + represents or the drive on which the directory or file resides. Objects + other than TYPE_SHARE or TYPE_FILESYSTEM will result + in 0L being returned. +

+

+
+
+
+ +
Returns:
the free disk space in bytes of the drive on which this file or + directory resides +
Throws: +
SmbException
+
+
+
+ +

+mkdir

+
+public void mkdir()
+           throws SmbException
+
+
Creates a directory with the path specified by this + SmbFile. For this method to be successful, the target + must not already exist. This method will fail when + used with smb://, smb://workgroup/, + smb://server/, or smb://server/share/ URLs + because workgroups, servers, and shares cannot be dynamically created + (although in the future it may be possible to create shares). +

+

+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+mkdirs

+
+public void mkdirs()
+            throws SmbException
+
+
Creates a directory with the path specified by this SmbFile + and any parent directories that do not exist. This method will fail + when used with smb://, smb://workgroup/, + smb://server/, or smb://server/share/ URLs + because workgroups, servers, and shares cannot be dynamically created + (although in the future it may be possible to create shares). +

+

+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+createNewFile

+
+public void createNewFile()
+                   throws SmbException
+
+
Create a new file but fail if it already exists. The check for + existance of the file and it's creation are an atomic operation with + respect to other filesystem activities. +

+

+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+setCreateTime

+
+public void setCreateTime(long time)
+                   throws SmbException
+
+
Set the create time of the file. The time is specified as milliseconds + from Jan 1, 1970 which is the same as that which is returned by the + createTime() method. +

+ This method does not apply to workgroups, servers, or shares. +

+

+
+
+
+
Parameters:
time - the create time as milliseconds since Jan 1, 1970 +
Throws: +
SmbException
+
+
+
+ +

+setLastModified

+
+public void setLastModified(long time)
+                     throws SmbException
+
+
Set the last modified time of the file. The time is specified as milliseconds + from Jan 1, 1970 which is the same as that which is returned by the + lastModified(), getLastModified(), and getDate() methods. +

+ This method does not apply to workgroups, servers, or shares. +

+

+
+
+
+
Parameters:
time - the last modified time as milliseconds since Jan 1, 1970 +
Throws: +
SmbException
+
+
+
+ +

+getAttributes

+
+public int getAttributes()
+                  throws SmbException
+
+
Return the attributes of this file. Attributes are represented as a + bitset that must be masked with ATTR_* constants to determine + if they are set or unset. The value returned is suitable for use with + the setAttributes() method. +

+

+
+
+
+ +
Returns:
the ATTR_* attributes associated with this file +
Throws: +
SmbException
+
+
+
+ +

+setAttributes

+
+public void setAttributes(int attrs)
+                   throws SmbException
+
+
Set the attributes of this file. Attributes are composed into a + bitset by bitwise ORing the ATTR_* constants. Setting the + value returned by getAttributes will result in both files + having the same attributes. +

+

+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+setReadOnly

+
+public void setReadOnly()
+                 throws SmbException
+
+
Make this file read-only. This is shorthand for setAttributes( + getAttributes() | ATTR_READ_ONLY ). +

+

+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+setReadWrite

+
+public void setReadWrite()
+                  throws SmbException
+
+
Turn off the read-only attribute of this file. This is shorthand for + setAttributes( getAttributes() & ~ATTR_READONLY ). +

+

+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+toURL

+
+public java.net.URL toURL()
+                   throws java.net.MalformedURLException
+
+
Deprecated. Use getURL() instead +

+

Returns a URL for this SmbFile. The + URL may be used as any other URL might to + access an SMB resource. Currently only retrieving data and information + is supported (i.e. no doOutput). +

+

+
+
+
+ +
Returns:
A new URL for this SmbFile +
Throws: +
java.net.MalformedURLException
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
Computes a hashCode for this file based on the URL string and IP + address if the server. The hashing function uses the hashcode of the + server address, the canonical representation of the URL, and does not + compare authentication information. In essance, two + SmbFile objects that refer to + the same file should generate the same hashcode provided it is possible + to make such a determination. +

+

+
+
+
+ +
Returns:
A hashcode for this abstract file +
Throws: +
SmbException
+
+
+
+ +

+pathNamesPossiblyEqual

+
+protected boolean pathNamesPossiblyEqual(java.lang.String path1,
+                                         java.lang.String path2)
+
+
+
+
+
+
+
+
+
+ +

+equals

+
+public boolean equals(java.lang.Object obj)
+
+
Tests to see if two SmbFile objects are equal. Two + SmbFile objects are equal when they reference the same SMB + resource. More specifically, two SmbFile objects are + equals if their server IP addresses are equal and the canonicalized + representation of their URLs, minus authentication parameters, are + case insensitivly and lexographically equal. +

+ For example, assuming the server angus resolves to the + 192.168.1.15 IP address, the below URLs would result in + SmbFiles that are equal. + +

+ smb://192.168.1.15/share/DIR/foo.txt
+ smb://angus/share/data/../dir/foo.txt
+ 
+

+

+
+
+
+
Parameters:
obj - Another SmbFile object to compare for equality +
Returns:
true if the two objects refer to the same SMB resource + and false otherwise +
Throws: +
SmbException
+
+
+
+ +

+toString

+
+public java.lang.String toString()
+
+
Returns the string representation of this SmbFile object. This will + be the same as the URL used to construct this SmbFile. + This method will return the same value + as getPath. +

+

+
+
+
+ +
Returns:
The original URL representation of this SMB resource +
Throws: +
SmbException
+
+
+
+ +

+getContentLength

+
+public int getContentLength()
+
+
This URLConnection method just returns the result of length(). +

+

+
+
+
+ +
Returns:
the length of this file or 0 if it refers to a directory
+
+
+
+ +

+getDate

+
+public long getDate()
+
+
This URLConnection method just returns the result of lastModified. +

+

+
+
+
+ +
Returns:
the last modified data as milliseconds since Jan 1, 1970
+
+
+
+ +

+getLastModified

+
+public long getLastModified()
+
+
This URLConnection method just returns the result of lastModified. +

+

+
+
+
+ +
Returns:
the last modified data as milliseconds since Jan 1, 1970
+
+
+
+ +

+getInputStream

+
+public java.io.InputStream getInputStream()
+                                   throws java.io.IOException
+
+
This URLConnection method just returns a new SmbFileInputStream created with this file. +

+

+
+
+
+ +
Throws: +
java.io.IOException - thrown by SmbFileInputStream constructor
+
+
+
+ +

+getOutputStream

+
+public java.io.OutputStream getOutputStream()
+                                     throws java.io.IOException
+
+
This URLConnection method just returns a new SmbFileOutputStream created with this file. +

+

+
+
+
+ +
Throws: +
java.io.IOException - thrown by SmbFileOutputStream constructor
+
+
+
+ +

+getSecurity

+
+public ACE[] getSecurity(boolean resolveSids)
+                  throws java.io.IOException
+
+
Return an array of Access Control Entry (ACE) objects representing + the security descriptor associated with this file or directory. + If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned. +

+

+
+
+
+
Parameters:
resolveSids - Attempt to resolve the SIDs within each ACE form + their numeric representation to their corresponding account names. +
Throws: +
java.io.IOException
+
+
+
+ +

+getShareSecurity

+
+public ACE[] getShareSecurity(boolean resolveSids)
+                       throws java.io.IOException
+
+
Return an array of Access Control Entry (ACE) objects representing + the share permissions on the share exporting this file or directory. + If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned. +

+ Note that this is different from calling getSecurity on a + share. There are actually two different ACLs for shares - the ACL on + the share and the ACL on the folder being shared. + Go to Computer Management + > System Tools > Shared Folders > Shares and + look at the Properties for a share. You will see two tabs - one + for "Share Permissions" and another for "Security". These correspond to + the ACLs returned by getShareSecurity and getSecurity + respectively. +

+

+
+
+
+
Parameters:
resolveSids - Attempt to resolve the SIDs within each ACE form + their numeric representation to their corresponding account names. +
Throws: +
java.io.IOException
+
+
+
+ +

+getSecurity

+
+public ACE[] getSecurity()
+                  throws java.io.IOException
+
+
Return an array of Access Control Entry (ACE) objects representing + the security descriptor associated with this file or directory. +

+ Initially, the SIDs within each ACE will not be resolved however when + getType(), getDomainName(), getAccountName(), + or toString() is called, the names will attempt to be + resolved. If the names cannot be resolved (e.g. due to temporary + network failure), the said methods will return default values (usually + S-X-Y-Z strings of fragments of). +

+ Alternatively getSecurity(true) may be used to resolve all + SIDs together and detect network failures. +

+

+
+
+
+ +
Throws: +
java.io.IOException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SmbFileFilter.html b/docs/api/jcifs/smb/SmbFileFilter.html new file mode 100644 index 0000000..99b0de1 --- /dev/null +++ b/docs/api/jcifs/smb/SmbFileFilter.html @@ -0,0 +1,218 @@ + + + + + + +SmbFileFilter (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Interface SmbFileFilter

+
+
All Known Implementing Classes:
DosFileFilter
+
+
+
+
public interface SmbFileFilter
+ +

+


+ +

+ + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanaccept(SmbFile file) + +
+           
+  +

+ + + + + + + + + + + + + + +
+Method Detail
+ +

+accept

+
+public boolean accept(SmbFile file)
+               throws SmbException
+
+
+ +
Throws: +
SmbException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SmbFileInputStream.html b/docs/api/jcifs/smb/SmbFileInputStream.html new file mode 100644 index 0000000..9085f24 --- /dev/null +++ b/docs/api/jcifs/smb/SmbFileInputStream.html @@ -0,0 +1,478 @@ + + + + + + +SmbFileInputStream (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class SmbFileInputStream

+
+java.lang.Object
+  extended byjava.io.InputStream
+      extended byjcifs.smb.SmbFileInputStream
+
+
+
+
public class SmbFileInputStream
extends java.io.InputStream
+ +

+This InputStream can read bytes from a file on an SMB file server. Offsets are 64 bits. +

+ +

+


+ +

+ + + + + + + + + + + + + + + + + + + +
+Constructor Summary
SmbFileInputStream(SmbFile file) + +
+          Creates an InputStream for reading bytes from a file on + an SMB server represented by the SmbFile parameter.
SmbFileInputStream(java.lang.String url) + +
+          Creates an InputStream for reading bytes from a file on + an SMB server addressed by the url parameter.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ intavailable() + +
+          This stream class is unbuffered.
+ voidclose() + +
+          Closes this input stream and releases any system resources associated with the stream.
+ intread() + +
+          Reads a byte of data from this input stream.
+ intread(byte[] b) + +
+          Reads up to b.length bytes of data from this input stream into an array of bytes.
+ intread(byte[] b, + int off, + int len) + +
+          Reads up to len bytes of data from this input stream into an array of bytes.
+ intreadDirect(byte[] b, + int off, + int len) + +
+           
+protected  java.io.IOExceptionseToIoe(SmbException se) + +
+           
+ longskip(long n) + +
+          Skip n bytes of data on this stream.
+ + + + + + + +
Methods inherited from class java.io.InputStream
mark, markSupported, reset
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+SmbFileInputStream

+
+public SmbFileInputStream(java.lang.String url)
+                   throws SmbException,
+                          java.net.MalformedURLException,
+                          java.net.UnknownHostException
+
+
Creates an InputStream for reading bytes from a file on + an SMB server addressed by the url parameter. See SmbFile for a detailed description and examples of the smb + URL syntax. +

+

Parameters:
url - An smb URL string representing the file to read from
+
+ +

+SmbFileInputStream

+
+public SmbFileInputStream(SmbFile file)
+                   throws SmbException,
+                          java.net.MalformedURLException,
+                          java.net.UnknownHostException
+
+
Creates an InputStream for reading bytes from a file on + an SMB server represented by the SmbFile parameter. See + SmbFile for a detailed description and examples of + the smb URL syntax. +

+

Parameters:
file - An SmbFile specifying the file to read from
+ + + + + + + + +
+Method Detail
+ +

+seToIoe

+
+protected java.io.IOException seToIoe(SmbException se)
+
+
+
+
+
+
+ +

+close

+
+public void close()
+           throws java.io.IOException
+
+
Closes this input stream and releases any system resources associated with the stream. +

+

+ +
Throws: +
java.io.IOException - if a network error occurs
+
+
+
+ +

+read

+
+public int read()
+         throws java.io.IOException
+
+
Reads a byte of data from this input stream. +

+

+ +
Throws: +
java.io.IOException - if a network error occurs
+
+
+
+ +

+read

+
+public int read(byte[] b)
+         throws java.io.IOException
+
+
Reads up to b.length bytes of data from this input stream into an array of bytes. +

+

+ +
Throws: +
java.io.IOException - if a network error occurs
+
+
+
+ +

+read

+
+public int read(byte[] b,
+                int off,
+                int len)
+         throws java.io.IOException
+
+
Reads up to len bytes of data from this input stream into an array of bytes. +

+

+ +
Throws: +
java.io.IOException - if a network error occurs
+
+
+
+ +

+readDirect

+
+public int readDirect(byte[] b,
+                      int off,
+                      int len)
+               throws java.io.IOException
+
+
+ +
Throws: +
java.io.IOException
+
+
+
+ +

+available

+
+public int available()
+              throws java.io.IOException
+
+
This stream class is unbuffered. Therefore this method will always + return 0 for streams connected to regular files. However, a + stream created from a Named Pipe this method will query the server using a + "peek named pipe" operation and return the number of available bytes + on the server. +

+

+ +
Throws: +
java.io.IOException
+
+
+
+ +

+skip

+
+public long skip(long n)
+          throws java.io.IOException
+
+
Skip n bytes of data on this stream. This operation will not result + in any IO with the server. Unlink InputStream value less than + the one provided will not be returned if it exceeds the end of the file + (if this is a problem let us know). +

+

+ +
Throws: +
java.io.IOException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SmbFileOutputStream.html b/docs/api/jcifs/smb/SmbFileOutputStream.html new file mode 100644 index 0000000..6e5b88f --- /dev/null +++ b/docs/api/jcifs/smb/SmbFileOutputStream.html @@ -0,0 +1,519 @@ + + + + + + +SmbFileOutputStream (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class SmbFileOutputStream

+
+java.lang.Object
+  extended byjava.io.OutputStream
+      extended byjcifs.smb.SmbFileOutputStream
+
+
+
+
public class SmbFileOutputStream
extends java.io.OutputStream
+ +

+This OutputStream can write bytes to a file on an SMB file server. +

+ +

+


+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Constructor Summary
SmbFileOutputStream(SmbFile file) + +
+          Creates an OutputStream for writing bytes to a file on + an SMB server represented by the SmbFile parameter.
SmbFileOutputStream(SmbFile file, + boolean append) + +
+          Creates an OutputStream for writing bytes to a file + on an SMB server addressed by the SmbFile parameter.
SmbFileOutputStream(java.lang.String url) + +
+          Creates an OutputStream for writing to a file + on an SMB server addressed by the URL parameter.
SmbFileOutputStream(java.lang.String url, + boolean append) + +
+          Creates an OutputStream for writing bytes to a file on an + SMB server addressed by the URL parameter.
SmbFileOutputStream(java.lang.String url, + int shareAccess) + +
+          Creates an OutputStream for writing bytes to a file + on an SMB server addressed by the SmbFile parameter.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ voidclose() + +
+          Closes this output stream and releases any system resources associated + with it.
+ booleanisOpen() + +
+           
+ voidwrite(byte[] b) + +
+          Writes b.length bytes from the specified byte array to this + file output stream.
+ voidwrite(byte[] b, + int off, + int len) + +
+          Writes len bytes from the specified byte array starting at + offset off to this file output stream.
+ voidwrite(int b) + +
+          Writes the specified byte to this file output stream.
+ voidwriteDirect(byte[] b, + int off, + int len, + int flags) + +
+          Just bypasses TransWaitNamedPipe - used by DCERPC bind.
+ + + + + + + +
Methods inherited from class java.io.OutputStream
flush
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+SmbFileOutputStream

+
+public SmbFileOutputStream(java.lang.String url)
+                    throws SmbException,
+                           java.net.MalformedURLException,
+                           java.net.UnknownHostException
+
+
Creates an OutputStream for writing to a file + on an SMB server addressed by the URL parameter. See SmbFile for a detailed description and examples of + the smb URL syntax. +

+

Parameters:
url - An smb URL string representing the file to write to
+
+ +

+SmbFileOutputStream

+
+public SmbFileOutputStream(SmbFile file)
+                    throws SmbException,
+                           java.net.MalformedURLException,
+                           java.net.UnknownHostException
+
+
Creates an OutputStream for writing bytes to a file on + an SMB server represented by the SmbFile parameter. See + SmbFile for a detailed description and examples of + the smb URL syntax. +

+

Parameters:
file - An SmbFile specifying the file to write to
+
+ +

+SmbFileOutputStream

+
+public SmbFileOutputStream(java.lang.String url,
+                           boolean append)
+                    throws SmbException,
+                           java.net.MalformedURLException,
+                           java.net.UnknownHostException
+
+
Creates an OutputStream for writing bytes to a file on an + SMB server addressed by the URL parameter. See SmbFile + for a detailed description and examples of the smb URL syntax. If the + second argument is true, then bytes will be written to the + end of the file rather than the beginning. +

+

Parameters:
url - An smb URL string representing the file to write to
append - Append to the end of file
+
+ +

+SmbFileOutputStream

+
+public SmbFileOutputStream(SmbFile file,
+                           boolean append)
+                    throws SmbException,
+                           java.net.MalformedURLException,
+                           java.net.UnknownHostException
+
+
Creates an OutputStream for writing bytes to a file + on an SMB server addressed by the SmbFile parameter. See + SmbFile for a detailed description and examples of + the smb URL syntax. If the second argument is true, then + bytes will be written to the end of the file rather than the beginning. +

+

Parameters:
file - An SmbFile representing the file to write to
append - Append to the end of file
+
+ +

+SmbFileOutputStream

+
+public SmbFileOutputStream(java.lang.String url,
+                           int shareAccess)
+                    throws SmbException,
+                           java.net.MalformedURLException,
+                           java.net.UnknownHostException
+
+
Creates an OutputStream for writing bytes to a file + on an SMB server addressed by the SmbFile parameter. See + SmbFile for a detailed description and examples of + the smb URL syntax. +

+The second parameter specifies how the file should be shared. If +SmbFile.FILE_NO_SHARE is specified the client will +have exclusive access to the file. An additional open command +from jCIFS or another application will fail with the "file is being +accessed by another process" error. The FILE_SHARE_READ, +FILE_SHARE_WRITE, and FILE_SHARE_DELETE may be +combined with the bitwise OR '|' to specify that other peocesses may read, +write, and/or delete the file while the jCIFS user has the file open. +

+

Parameters:
url - An smb URL representing the file to write to
shareAccess - File sharing flag: SmbFile.FILE_NOSHARE or any combination of SmbFile.FILE_READ, SmbFile.FILE_WRITE, and SmbFile.FILE_DELETE
+ + + + + + + + +
+Method Detail
+ +

+close

+
+public void close()
+           throws java.io.IOException
+
+
Closes this output stream and releases any system resources associated + with it. +

+

+ +
Throws: +
java.io.IOException - if a network error occurs
+
+
+
+ +

+write

+
+public void write(int b)
+           throws java.io.IOException
+
+
Writes the specified byte to this file output stream. +

+

+ +
Throws: +
java.io.IOException - if a network error occurs
+
+
+
+ +

+write

+
+public void write(byte[] b)
+           throws java.io.IOException
+
+
Writes b.length bytes from the specified byte array to this + file output stream. +

+

+ +
Throws: +
java.io.IOException - if a network error occurs
+
+
+
+ +

+isOpen

+
+public boolean isOpen()
+
+
+
+
+
+
+ +

+write

+
+public void write(byte[] b,
+                  int off,
+                  int len)
+           throws java.io.IOException
+
+
Writes len bytes from the specified byte array starting at + offset off to this file output stream. +

+

+
Parameters:
b - The array +
Throws: +
java.io.IOException - if a network error occurs
+
+
+
+ +

+writeDirect

+
+public void writeDirect(byte[] b,
+                        int off,
+                        int len,
+                        int flags)
+                 throws java.io.IOException
+
+
Just bypasses TransWaitNamedPipe - used by DCERPC bind. +

+

+ +
Throws: +
java.io.IOException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SmbFilenameFilter.html b/docs/api/jcifs/smb/SmbFilenameFilter.html new file mode 100644 index 0000000..4f3ac9b --- /dev/null +++ b/docs/api/jcifs/smb/SmbFilenameFilter.html @@ -0,0 +1,217 @@ + + + + + + +SmbFilenameFilter (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Interface SmbFilenameFilter

+
+
+
public interface SmbFilenameFilter
+ +

+


+ +

+ + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanaccept(SmbFile dir, + java.lang.String name) + +
+           
+  +

+ + + + + + + + + + + + + + +
+Method Detail
+ +

+accept

+
+public boolean accept(SmbFile dir,
+                      java.lang.String name)
+               throws SmbException
+
+
+ +
Throws: +
SmbException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SmbNamedPipe.html b/docs/api/jcifs/smb/SmbNamedPipe.html new file mode 100644 index 0000000..bcee123 --- /dev/null +++ b/docs/api/jcifs/smb/SmbNamedPipe.html @@ -0,0 +1,573 @@ + + + + + + +SmbNamedPipe (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class SmbNamedPipe

+
+java.lang.Object
+  extended byjava.net.URLConnection
+      extended byjcifs.smb.SmbFile
+          extended byjcifs.smb.SmbNamedPipe
+
+
+
All Implemented Interfaces:
jcifs.smb.SmbConstants
+
+
+
+
public class SmbNamedPipe
extends SmbFile
+ +

+This class will allow a Java program to read and write data to Named + Pipes and Transact NamedPipes. + +

There are three Win32 function calls provided by the Windows SDK + that are important in the context of using jCIFS. They are: + +

    +
  • CallNamedPipe A message-type pipe call that opens, + writes to, reads from, and closes the pipe in a single operation. +
  • TransactNamedPipe A message-type pipe call that + writes to and reads from an existing pipe descriptor in one operation. +
  • CreateFile, ReadFile, + WriteFile, and CloseFile A byte-type pipe can + be opened, written to, read from and closed using the standard Win32 + file operations. +
+ +

The jCIFS API maps all of these operations into the standard Java + XxxputStream interface. A special PIPE_TYPE + flags is necessary to distinguish which type of Named Pipe behavior + is desired. + +

+ + + + + + +
SmbNamedPipe Constructor Examples
Code SampleDescription
+ new SmbNamedPipe( "smb://server/IPC$/PIPE/foo",
+         SmbNamedPipe.PIPE_TYPE_RDWR |
+         SmbNamedPipe.PIPE_TYPE_CALL );
+ 
+ Open the Named Pipe foo for reading and writing. The pipe will behave like the CallNamedPipe interface. +
+ new SmbNamedPipe( "smb://server/IPC$/foo",
+         SmbNamedPipe.PIPE_TYPE_RDWR |
+         SmbNamedPipe.PIPE_TYPE_TRANSACT );
+ 
+ Open the Named Pipe foo for reading and writing. The pipe will behave like the TransactNamedPipe interface. +
+ new SmbNamedPipe( "smb://server/IPC$/foo",
+         SmbNamedPipe.PIPE_TYPE_RDWR );
+ 
+ Open the Named Pipe foo for reading and writing. The pipe will + behave as though the CreateFile, ReadFile, + WriteFile, and CloseFile interface was + being used. +
+ +

See Using jCIFS to Connect to Win32 + Named Pipes for a detailed description of how to use jCIFS with + Win32 Named Pipe server processes. +

+ +

+


+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Field Summary
+static intPIPE_TYPE_CALL + +
+          Pipe operations should behave like the CallNamedPipe Win32 Named Pipe function.
+static intPIPE_TYPE_DCE_TRANSACT + +
+           
+static intPIPE_TYPE_RDONLY + +
+          The pipe should be opened read-only.
+static intPIPE_TYPE_RDWR + +
+          The pipe should be opened for both reading and writing.
+static intPIPE_TYPE_TRANSACT + +
+          Pipe operations should behave like the TransactNamedPipe Win32 Named Pipe function.
+static intPIPE_TYPE_WRONLY + +
+          The pipe should be opened only for writing.
+ + + + + + + +
Fields inherited from class jcifs.smb.SmbFile
ATTR_ARCHIVE, ATTR_DIRECTORY, ATTR_HIDDEN, ATTR_READONLY, ATTR_SYSTEM, ATTR_VOLUME, CAP_DFS, CAP_EXTENDED_SECURITY, CAP_LARGE_FILES, CAP_LEVEL_II_OPLOCKS, CAP_LOCK_AND_READ, CAP_MPX_MODE, CAP_NONE, CAP_NT_FIND, CAP_NT_SMBS, CAP_RAW_MODE, CAP_RPC_REMOTE_APIS, CAP_STATUS32, CAP_UNICODE, CAPABILITIES, CMD_OFFSET, CONNECTIONS, DEFAULT_CAPABILITIES, DEFAULT_FLAGS2, DEFAULT_MAX_MPX_COUNT, DEFAULT_PORT, DEFAULT_RCV_BUF_SIZE, DEFAULT_RESPONSE_TIMEOUT, DEFAULT_SND_BUF_SIZE, DEFAULT_SO_TIMEOUT, DEFAULT_SSN_LIMIT, DELETE, dfs, ERROR_CODE_OFFSET, FILE_APPEND_DATA, FILE_DELETE, FILE_EXECUTE, FILE_NO_SHARE, FILE_READ_ATTRIBUTES, FILE_READ_DATA, FILE_READ_EA, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_WRITE_ATTRIBUTES, FILE_WRITE_DATA, FILE_WRITE_EA, FLAGS_COPY_SOURCE_MODE_ASCII, FLAGS_COPY_TARGET_MODE_ASCII, FLAGS_LOCK_AND_READ_WRITE_AND_UNLOCK, FLAGS_NONE, FLAGS_NOTIFY_OF_MODIFY_ACTION, FLAGS_OFFSET, FLAGS_OPLOCK_REQUESTED_OR_GRANTED, FLAGS_PATH_NAMES_CANONICALIZED, FLAGS_PATH_NAMES_CASELESS, FLAGS_RECEIVE_BUFFER_POSTED, FLAGS_RESPONSE, FLAGS_TARGET_MUST_BE_DIRECTORY, FLAGS_TARGET_MUST_BE_FILE, FLAGS_TREE_COPY, FLAGS_VERIFY_ALL_WRITES, FLAGS2, FLAGS2_EXTENDED_ATTRIBUTES, FLAGS2_EXTENDED_SECURITY_NEGOTIATION, FLAGS2_LONG_FILENAMES, FLAGS2_NONE, FLAGS2_PERMIT_READ_IF_EXECUTE_PERM, FLAGS2_RESOLVE_PATHS_IN_DFS, FLAGS2_SECURITY_SIGNATURES, FLAGS2_STATUS32, FLAGS2_UNICODE, FORCE_UNICODE, GENERIC_ALL, GENERIC_EXECUTE, GENERIC_READ, GENERIC_WRITE, HEADER_LENGTH, LADDR, LM_COMPATIBILITY, LPORT, MAX_MPX_COUNT, MILLISECONDS_BETWEEN_1970_AND_1601, NATIVE_LANMAN, NATIVE_OS, NETBIOS_HOSTNAME, NULL_TRANSPORT, OEM_ENCODING, OPEN_FUNCTION_FAIL_IF_EXISTS, OPEN_FUNCTION_OVERWRITE_IF_EXISTS, PID, RCV_BUF_SIZE, READ_CONTROL, RESPONSE_TIMEOUT, SECURITY_SHARE, SECURITY_USER, SIGNATURE_OFFSET, SIGNPREF, SND_BUF_SIZE, SO_TIMEOUT, SSN_LIMIT, SYNCHRONIZE, TCP_NODELAY, TID_OFFSET, TYPE_COMM, TYPE_FILESYSTEM, TYPE_NAMED_PIPE, TYPE_PRINTER, TYPE_SERVER, TYPE_SHARE, TYPE_WORKGROUP, TZ, UNI_ENCODING, USE_BATCHING, USE_EXTSEC, USE_NTSMBS, USE_NTSTATUS, USE_UNICODE, VC_NUMBER, WRITE_DAC, WRITE_OWNER
+ + + + + + + +
Fields inherited from class java.net.URLConnection
allowUserInteraction, connected, doInput, doOutput, ifModifiedSince, url, useCaches
+  + + + + + + + + + + + + + + + + +
+Constructor Summary
SmbNamedPipe(java.lang.String url, + int pipeType) + +
+          Open the Named Pipe resource specified by the url + parameter.
SmbNamedPipe(java.lang.String url, + int pipeType, + NtlmPasswordAuthentication auth) + +
+           
SmbNamedPipe(java.net.URL url, + int pipeType, + NtlmPasswordAuthentication auth) + +
+           
+  + + + + + + + + + + + + + + + +
+Method Summary
+ java.io.InputStreamgetNamedPipeInputStream() + +
+          Return the InputStream used to read information + from this pipe instance.
+ java.io.OutputStreamgetNamedPipeOutputStream() + +
+          Return the OutputStream used to write + information to this pipe instance.
+ + + + + + + +
Methods inherited from class jcifs.smb.SmbFile
canRead, canWrite, connect, copyTo, createNewFile, createTime, delete, equals, exists, getAttributes, getCanonicalPath, getContentLength, getDate, getDfsPath, getDiskFreeSpace, getInputStream, getLastModified, getName, getOutputStream, getParent, getPath, getPrincipal, getSecurity, getSecurity, getServer, getShare, getShareSecurity, getType, getUncPath, hashCode, isDirectory, isFile, isHidden, lastModified, length, list, list, listFiles, listFiles, listFiles, listFiles, mkdir, mkdirs, pathNamesPossiblyEqual, renameTo, setAttributes, setCreateTime, setLastModified, setReadOnly, setReadWrite, toString, toURL
+ + + + + + + +
Methods inherited from class java.net.URLConnection
addRequestProperty, getAllowUserInteraction, getContent, getContent, getContentEncoding, getContentType, getDefaultAllowUserInteraction, getDefaultRequestProperty, getDefaultUseCaches, getDoInput, getDoOutput, getExpiration, getFileNameMap, getHeaderField, getHeaderField, getHeaderFieldDate, getHeaderFieldInt, getHeaderFieldKey, getHeaderFields, getIfModifiedSince, getPermission, getRequestProperties, getRequestProperty, getURL, getUseCaches, guessContentTypeFromName, guessContentTypeFromStream, setAllowUserInteraction, setContentHandlerFactory, setDefaultAllowUserInteraction, setDefaultRequestProperty, setDefaultUseCaches, setDoInput, setDoOutput, setFileNameMap, setIfModifiedSince, setRequestProperty, setUseCaches
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Field Detail
+ +

+PIPE_TYPE_RDONLY

+
+public static final int PIPE_TYPE_RDONLY
+
+
The pipe should be opened read-only. +

+

+
See Also:
Constant Field Values
+
+
+ +

+PIPE_TYPE_WRONLY

+
+public static final int PIPE_TYPE_WRONLY
+
+
The pipe should be opened only for writing. +

+

+
See Also:
Constant Field Values
+
+
+ +

+PIPE_TYPE_RDWR

+
+public static final int PIPE_TYPE_RDWR
+
+
The pipe should be opened for both reading and writing. +

+

+
See Also:
Constant Field Values
+
+
+ +

+PIPE_TYPE_CALL

+
+public static final int PIPE_TYPE_CALL
+
+
Pipe operations should behave like the CallNamedPipe Win32 Named Pipe function. +

+

+
See Also:
Constant Field Values
+
+
+ +

+PIPE_TYPE_TRANSACT

+
+public static final int PIPE_TYPE_TRANSACT
+
+
Pipe operations should behave like the TransactNamedPipe Win32 Named Pipe function. +

+

+
See Also:
Constant Field Values
+
+
+ +

+PIPE_TYPE_DCE_TRANSACT

+
+public static final int PIPE_TYPE_DCE_TRANSACT
+
+
+
See Also:
Constant Field Values
+
+ + + + + + + + +
+Constructor Detail
+ +

+SmbNamedPipe

+
+public SmbNamedPipe(java.lang.String url,
+                    int pipeType)
+             throws java.net.MalformedURLException,
+                    java.net.UnknownHostException
+
+
Open the Named Pipe resource specified by the url + parameter. The pipeType parameter should be at least one of + the PIPE_TYPE flags combined with the bitwise OR + operator |. See the examples listed above. +

+

+
+ +

+SmbNamedPipe

+
+public SmbNamedPipe(java.lang.String url,
+                    int pipeType,
+                    NtlmPasswordAuthentication auth)
+             throws java.net.MalformedURLException,
+                    java.net.UnknownHostException
+
+
+
+ +

+SmbNamedPipe

+
+public SmbNamedPipe(java.net.URL url,
+                    int pipeType,
+                    NtlmPasswordAuthentication auth)
+             throws java.net.MalformedURLException,
+                    java.net.UnknownHostException
+
+
+ + + + + + + + +
+Method Detail
+ +

+getNamedPipeInputStream

+
+public java.io.InputStream getNamedPipeInputStream()
+                                            throws java.io.IOException
+
+
Return the InputStream used to read information + from this pipe instance. Presumably data would first be written + to the OutputStream associated with this Named + Pipe instance although this is not a requirement (e.g. a + read-only named pipe would write data to this stream on + connection). Reading from this stream may block. Therefore it + may be necessary that an addition thread be used to read and + write to a Named Pipe. +

+

+ +
Throws: +
java.io.IOException
+
+
+
+ +

+getNamedPipeOutputStream

+
+public java.io.OutputStream getNamedPipeOutputStream()
+                                              throws java.io.IOException
+
+
Return the OutputStream used to write + information to this pipe instance. The act of writing data + to this stream will result in response data recieved in the + InputStream associated with this Named Pipe + instance (unless of course it does not elicite a response or the pipe is write-only). +

+

+ +
Throws: +
java.io.IOException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/SmbRandomAccessFile.html b/docs/api/jcifs/smb/SmbRandomAccessFile.html new file mode 100644 index 0000000..74f60e8 --- /dev/null +++ b/docs/api/jcifs/smb/SmbRandomAccessFile.html @@ -0,0 +1,1199 @@ + + + + + + +SmbRandomAccessFile (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.smb +
+Class SmbRandomAccessFile

+
+java.lang.Object
+  extended byjcifs.smb.SmbRandomAccessFile
+
+
+
All Implemented Interfaces:
java.io.DataInput, java.io.DataOutput
+
+
+
+
public class SmbRandomAccessFile
extends java.lang.Object
implements java.io.DataOutput, java.io.DataInput
+ +

+


+ +

+ + + + + + + + + + + + + + + + + + + +
+Constructor Summary
SmbRandomAccessFile(SmbFile file, + java.lang.String mode) + +
+           
SmbRandomAccessFile(java.lang.String url, + java.lang.String mode, + int shareAccess) + +
+           
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ voidclose() + +
+           
+ longgetFilePointer() + +
+           
+ longlength() + +
+           
+ intread() + +
+           
+ intread(byte[] b) + +
+           
+ intread(byte[] b, + int off, + int len) + +
+           
+ booleanreadBoolean() + +
+           
+ bytereadByte() + +
+           
+ charreadChar() + +
+           
+ doublereadDouble() + +
+           
+ floatreadFloat() + +
+           
+ voidreadFully(byte[] b) + +
+           
+ voidreadFully(byte[] b, + int off, + int len) + +
+           
+ intreadInt() + +
+           
+ java.lang.StringreadLine() + +
+           
+ longreadLong() + +
+           
+ shortreadShort() + +
+           
+ intreadUnsignedByte() + +
+           
+ intreadUnsignedShort() + +
+           
+ java.lang.StringreadUTF() + +
+           
+ voidseek(long pos) + +
+           
+ voidsetLength(long newLength) + +
+           
+ intskipBytes(int n) + +
+           
+ voidwrite(byte[] b) + +
+           
+ voidwrite(byte[] b, + int off, + int len) + +
+           
+ voidwrite(int b) + +
+           
+ voidwriteBoolean(boolean v) + +
+           
+ voidwriteByte(int v) + +
+           
+ voidwriteBytes(java.lang.String s) + +
+           
+ voidwriteChar(int v) + +
+           
+ voidwriteChars(java.lang.String s) + +
+           
+ voidwriteDouble(double v) + +
+           
+ voidwriteFloat(float v) + +
+           
+ voidwriteInt(int v) + +
+           
+ voidwriteLong(long v) + +
+           
+ voidwriteShort(int v) + +
+           
+ voidwriteUTF(java.lang.String str) + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+SmbRandomAccessFile

+
+public SmbRandomAccessFile(java.lang.String url,
+                           java.lang.String mode,
+                           int shareAccess)
+                    throws SmbException,
+                           java.net.MalformedURLException,
+                           java.net.UnknownHostException
+
+
+
+ +

+SmbRandomAccessFile

+
+public SmbRandomAccessFile(SmbFile file,
+                           java.lang.String mode)
+                    throws SmbException,
+                           java.net.MalformedURLException,
+                           java.net.UnknownHostException
+
+
+ + + + + + + + +
+Method Detail
+ +

+read

+
+public int read()
+         throws SmbException
+
+
+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+read

+
+public int read(byte[] b)
+         throws SmbException
+
+
+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+read

+
+public int read(byte[] b,
+                int off,
+                int len)
+         throws SmbException
+
+
+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readFully

+
+public final void readFully(byte[] b)
+                     throws SmbException
+
+
+
Specified by:
readFully in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readFully

+
+public final void readFully(byte[] b,
+                            int off,
+                            int len)
+                     throws SmbException
+
+
+
Specified by:
readFully in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+skipBytes

+
+public int skipBytes(int n)
+              throws SmbException
+
+
+
Specified by:
skipBytes in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+write

+
+public void write(int b)
+           throws SmbException
+
+
+
Specified by:
write in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+write

+
+public void write(byte[] b)
+           throws SmbException
+
+
+
Specified by:
write in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+write

+
+public void write(byte[] b,
+                  int off,
+                  int len)
+           throws SmbException
+
+
+
Specified by:
write in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+getFilePointer

+
+public long getFilePointer()
+                    throws SmbException
+
+
+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+seek

+
+public void seek(long pos)
+          throws SmbException
+
+
+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+length

+
+public long length()
+            throws SmbException
+
+
+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+setLength

+
+public void setLength(long newLength)
+               throws SmbException
+
+
+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+close

+
+public void close()
+           throws SmbException
+
+
+
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readBoolean

+
+public final boolean readBoolean()
+                          throws SmbException
+
+
+
Specified by:
readBoolean in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readByte

+
+public final byte readByte()
+                    throws SmbException
+
+
+
Specified by:
readByte in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readUnsignedByte

+
+public final int readUnsignedByte()
+                           throws SmbException
+
+
+
Specified by:
readUnsignedByte in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readShort

+
+public final short readShort()
+                      throws SmbException
+
+
+
Specified by:
readShort in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readUnsignedShort

+
+public final int readUnsignedShort()
+                            throws SmbException
+
+
+
Specified by:
readUnsignedShort in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readChar

+
+public final char readChar()
+                    throws SmbException
+
+
+
Specified by:
readChar in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readInt

+
+public final int readInt()
+                  throws SmbException
+
+
+
Specified by:
readInt in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readLong

+
+public final long readLong()
+                    throws SmbException
+
+
+
Specified by:
readLong in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readFloat

+
+public final float readFloat()
+                      throws SmbException
+
+
+
Specified by:
readFloat in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readDouble

+
+public final double readDouble()
+                        throws SmbException
+
+
+
Specified by:
readDouble in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readLine

+
+public final java.lang.String readLine()
+                                throws SmbException
+
+
+
Specified by:
readLine in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+readUTF

+
+public final java.lang.String readUTF()
+                               throws SmbException
+
+
+
Specified by:
readUTF in interface java.io.DataInput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeBoolean

+
+public final void writeBoolean(boolean v)
+                        throws SmbException
+
+
+
Specified by:
writeBoolean in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeByte

+
+public final void writeByte(int v)
+                     throws SmbException
+
+
+
Specified by:
writeByte in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeShort

+
+public final void writeShort(int v)
+                      throws SmbException
+
+
+
Specified by:
writeShort in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeChar

+
+public final void writeChar(int v)
+                     throws SmbException
+
+
+
Specified by:
writeChar in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeInt

+
+public final void writeInt(int v)
+                    throws SmbException
+
+
+
Specified by:
writeInt in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeLong

+
+public final void writeLong(long v)
+                     throws SmbException
+
+
+
Specified by:
writeLong in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeFloat

+
+public final void writeFloat(float v)
+                      throws SmbException
+
+
+
Specified by:
writeFloat in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeDouble

+
+public final void writeDouble(double v)
+                       throws SmbException
+
+
+
Specified by:
writeDouble in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeBytes

+
+public final void writeBytes(java.lang.String s)
+                      throws SmbException
+
+
+
Specified by:
writeBytes in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeChars

+
+public final void writeChars(java.lang.String s)
+                      throws SmbException
+
+
+
Specified by:
writeChars in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+
+ +

+writeUTF

+
+public final void writeUTF(java.lang.String str)
+                    throws SmbException
+
+
+
Specified by:
writeUTF in interface java.io.DataOutput
+
+
+ +
Throws: +
SmbException
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/ACE.html b/docs/api/jcifs/smb/class-use/ACE.html new file mode 100644 index 0000000..3141988 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/ACE.html @@ -0,0 +1,191 @@ + + + + + + +Uses of Class jcifs.smb.ACE (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.ACE

+
+ + + + + + + + + +
+Packages that use ACE
jcifs.smb  
+  +

+ + + + + +
+Uses of ACE in jcifs.smb
+  +

+ + + + + + + + + + + + + + + + + +
Methods in jcifs.smb that return ACE
+ ACE[]SmbFile.getSecurity(boolean resolveSids) + +
+          Return an array of Access Control Entry (ACE) objects representing + the security descriptor associated with this file or directory.
+ ACE[]SmbFile.getShareSecurity(boolean resolveSids) + +
+          Return an array of Access Control Entry (ACE) objects representing + the share permissions on the share exporting this file or directory.
+ ACE[]SmbFile.getSecurity() + +
+          Return an array of Access Control Entry (ACE) objects representing + the security descriptor associated with this file or directory.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/DosFileFilter.html b/docs/api/jcifs/smb/class-use/DosFileFilter.html new file mode 100644 index 0000000..700fbb0 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/DosFileFilter.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.smb.DosFileFilter (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.DosFileFilter

+
+No usage of jcifs.smb.DosFileFilter +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/NtlmAuthenticator.html b/docs/api/jcifs/smb/class-use/NtlmAuthenticator.html new file mode 100644 index 0000000..33d0347 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/NtlmAuthenticator.html @@ -0,0 +1,172 @@ + + + + + + +Uses of Class jcifs.smb.NtlmAuthenticator (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.NtlmAuthenticator

+
+ + + + + + + + + +
+Packages that use NtlmAuthenticator
jcifs.smb  
+  +

+ + + + + +
+Uses of NtlmAuthenticator in jcifs.smb
+  +

+ + + + + + + + + +
Methods in jcifs.smb with parameters of type NtlmAuthenticator
+static voidNtlmAuthenticator.setDefault(NtlmAuthenticator a) + +
+          Set the default NtlmAuthenticator.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/NtlmContext.html b/docs/api/jcifs/smb/class-use/NtlmContext.html new file mode 100644 index 0000000..7db4a3c --- /dev/null +++ b/docs/api/jcifs/smb/class-use/NtlmContext.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.smb.NtlmContext (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.NtlmContext

+
+No usage of jcifs.smb.NtlmContext +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/NtlmPasswordAuthentication.html b/docs/api/jcifs/smb/class-use/NtlmPasswordAuthentication.html new file mode 100644 index 0000000..dcb9c6e --- /dev/null +++ b/docs/api/jcifs/smb/class-use/NtlmPasswordAuthentication.html @@ -0,0 +1,330 @@ + + + + + + +Uses of Class jcifs.smb.NtlmPasswordAuthentication (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.NtlmPasswordAuthentication

+
+ + + + + + + + + +
+Packages that use NtlmPasswordAuthentication
jcifs.smb  
+  +

+ + + + + +
+Uses of NtlmPasswordAuthentication in jcifs.smb
+  +

+ + + + + + + + + +
Fields in jcifs.smb declared as NtlmPasswordAuthentication
+static NtlmPasswordAuthenticationNtlmPasswordAuthentication.ANONYMOUS + +
+           
+  +

+ + + + + + + + + + + + + +
Methods in jcifs.smb that return NtlmPasswordAuthentication
+static NtlmPasswordAuthenticationNtlmAuthenticator.requestNtlmPasswordAuthentication(java.lang.String url, + SmbAuthException sae) + +
+          Used internally by jCIFS when an SmbAuthException is trapped to retrieve new user credentials.
+protected  NtlmPasswordAuthenticationNtlmAuthenticator.getNtlmPasswordAuthentication() + +
+          An application extending this class must provide an implementation for this method that returns new user credentials try try when accessing SMB resources described by the getRequestingURL and getRequestingException methods.
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in jcifs.smb with parameters of type NtlmPasswordAuthentication
+static voidSID.resolveSids(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids, + int offset, + int length) + +
+           
+static voidSID.resolveSids(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids) + +
+          Resolve an array of SIDs using a cache and at most one MSRPC request.
+static SIDSID.getServerSid(java.lang.String server, + NtlmPasswordAuthentication auth) + +
+           
+ voidSID.resolve(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth) + +
+          Manually resolve this SID.
+ SID[]SID.getGroupMemberSids(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth, + int flags) + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Constructors in jcifs.smb with parameters of type NtlmPasswordAuthentication
NtlmContext(NtlmPasswordAuthentication auth, + boolean doSigning) + +
+           
SmbFile(java.lang.String url, + NtlmPasswordAuthentication auth) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(java.lang.String url, + NtlmPasswordAuthentication auth, + int shareAccess) + +
+          Constructs an SmbFile representing a file on an SMB network.
SmbFile(java.lang.String context, + java.lang.String name, + NtlmPasswordAuthentication auth) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(java.lang.String context, + java.lang.String name, + NtlmPasswordAuthentication auth, + int shareAccess) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(java.net.URL url, + NtlmPasswordAuthentication auth) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory from a URL object and an + NtlmPasswordAuthentication object.
SmbNamedPipe(java.lang.String url, + int pipeType, + NtlmPasswordAuthentication auth) + +
+           
SmbNamedPipe(java.net.URL url, + int pipeType, + NtlmPasswordAuthentication auth) + +
+           
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SID.html b/docs/api/jcifs/smb/class-use/SID.html new file mode 100644 index 0000000..d93ec67 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SID.html @@ -0,0 +1,277 @@ + + + + + + +Uses of Class jcifs.smb.SID (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.SID

+
+ + + + + + + + + +
+Packages that use SID
jcifs.smb  
+  +

+ + + + + +
+Uses of SID in jcifs.smb
+  +

+ + + + + + + + + + + + + + + + + +
Fields in jcifs.smb declared as SID
+static SIDSID.EVERYONE + +
+           
+static SIDSID.CREATOR_OWNER + +
+           
+static SIDSID.SYSTEM + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in jcifs.smb that return SID
+ SIDACE.getSID() + +
+          Return the SID associated with this ACE.
+static SIDSID.getServerSid(java.lang.String server, + NtlmPasswordAuthentication auth) + +
+           
+ SIDSID.getDomainSid() + +
+           
+ SID[]SID.getGroupMemberSids(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth, + int flags) + +
+           
+  +

+ + + + + + + + + + + + + +
Methods in jcifs.smb with parameters of type SID
+static voidSID.resolveSids(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids, + int offset, + int length) + +
+           
+static voidSID.resolveSids(java.lang.String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids) + +
+          Resolve an array of SIDs using a cache and at most one MSRPC request.
+  +

+ + + + + + + + +
Constructors in jcifs.smb with parameters of type SID
SID(SID domsid, + int rid) + +
+          Construct a SID from a domain SID and an RID + (relative identifier).
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SmbAuthException.html b/docs/api/jcifs/smb/class-use/SmbAuthException.html new file mode 100644 index 0000000..1b346f5 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SmbAuthException.html @@ -0,0 +1,189 @@ + + + + + + +Uses of Class jcifs.smb.SmbAuthException (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.SmbAuthException

+
+ + + + + + + + + +
+Packages that use SmbAuthException
jcifs.smb  
+  +

+ + + + + +
+Uses of SmbAuthException in jcifs.smb
+  +

+ + + + + + + + + +
Methods in jcifs.smb that return SmbAuthException
+protected  SmbAuthExceptionNtlmAuthenticator.getRequestingException() + +
+           
+  +

+ + + + + + + + + +
Methods in jcifs.smb with parameters of type SmbAuthException
+static NtlmPasswordAuthenticationNtlmAuthenticator.requestNtlmPasswordAuthentication(java.lang.String url, + SmbAuthException sae) + +
+          Used internally by jCIFS when an SmbAuthException is trapped to retrieve new user credentials.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SmbException.html b/docs/api/jcifs/smb/class-use/SmbException.html new file mode 100644 index 0000000..6acf6f5 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SmbException.html @@ -0,0 +1,878 @@ + + + + + + +Uses of Class jcifs.smb.SmbException (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.SmbException

+
+ + + + + + + + + +
+Packages that use SmbException
jcifs.smb  
+  +

+ + + + + +
+Uses of SmbException in jcifs.smb
+  +

+ + + + + + + + + +
Subclasses of SmbException in jcifs.smb
+ classSmbAuthException + +
+          The SmbAuthException encapsulates the variety of + authentication related error codes returned by an SMB server.
+  +

+ + + + + + + + + +
Methods in jcifs.smb with parameters of type SmbException
+protected  java.io.IOExceptionSmbFileInputStream.seToIoe(SmbException se) + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in jcifs.smb that throw SmbException
+ booleanDosFileFilter.accept(SmbFile file) + +
+           
+ byte[]NtlmContext.initSecContext(byte[] token, + int offset, + int len) + +
+           
+ byte[]NtlmPasswordAuthentication.getSigningKey(byte[] challenge) + +
+           
+ intSmbFile.getType() + +
+          Returns type of of object this SmbFile represents.
+ booleanSmbFile.exists() + +
+          Tests to see if the SMB resource exists.
+ booleanSmbFile.canRead() + +
+          Tests to see if the file this SmbFile represents can be + read.
+ booleanSmbFile.canWrite() + +
+          Tests to see if the file this SmbFile represents + exists and is not marked read-only.
+ booleanSmbFile.isDirectory() + +
+          Tests to see if the file this SmbFile represents is a directory.
+ booleanSmbFile.isFile() + +
+          Tests to see if the file this SmbFile represents is not a directory.
+ booleanSmbFile.isHidden() + +
+          Tests to see if the file this SmbFile represents is marked as + hidden.
+ java.lang.StringSmbFile.getDfsPath() + +
+          If the path of this SmbFile falls within a DFS volume, + this method will return the referral path to which it maps.
+ longSmbFile.createTime() + +
+          Retrieve the time this SmbFile was created.
+ longSmbFile.lastModified() + +
+          Retrieve the last time the file represented by this + SmbFile was modified.
+ java.lang.String[]SmbFile.list() + +
+          List the contents of this SMB resource.
+ java.lang.String[]SmbFile.list(SmbFilenameFilter filter) + +
+          List the contents of this SMB resource.
+ SmbFile[]SmbFile.listFiles() + +
+          List the contents of this SMB resource as an array of + SmbFile objects.
+ SmbFile[]SmbFile.listFiles(java.lang.String wildcard) + +
+          The CIFS protocol provides for DOS "wildcards" to be used as + a performance enhancement.
+ SmbFile[]SmbFile.listFiles(SmbFilenameFilter filter) + +
+          List the contents of this SMB resource.
+ SmbFile[]SmbFile.listFiles(SmbFileFilter filter) + +
+          List the contents of this SMB resource.
+ voidSmbFile.renameTo(SmbFile dest) + +
+          Changes the name of the file this SmbFile represents to the name + designated by the SmbFile argument.
+ voidSmbFile.copyTo(SmbFile dest) + +
+          This method will copy the file or directory represented by this + SmbFile and it's sub-contents to the location specified by the + dest parameter.
+ voidSmbFile.delete() + +
+          This method will delete the file or directory specified by this + SmbFile.
+ longSmbFile.length() + +
+          Returns the length of this SmbFile in bytes.
+ longSmbFile.getDiskFreeSpace() + +
+          This method returns the free disk space in bytes of the drive this share + represents or the drive on which the directory or file resides.
+ voidSmbFile.mkdir() + +
+          Creates a directory with the path specified by this + SmbFile.
+ voidSmbFile.mkdirs() + +
+          Creates a directory with the path specified by this SmbFile + and any parent directories that do not exist.
+ voidSmbFile.createNewFile() + +
+          Create a new file but fail if it already exists.
+ voidSmbFile.setCreateTime(long time) + +
+          Set the create time of the file.
+ voidSmbFile.setLastModified(long time) + +
+          Set the last modified time of the file.
+ intSmbFile.getAttributes() + +
+          Return the attributes of this file.
+ voidSmbFile.setAttributes(int attrs) + +
+          Set the attributes of this file.
+ voidSmbFile.setReadOnly() + +
+          Make this file read-only.
+ voidSmbFile.setReadWrite() + +
+          Turn off the read-only attribute of this file.
+ booleanSmbFileFilter.accept(SmbFile file) + +
+           
+ booleanSmbFilenameFilter.accept(SmbFile dir, + java.lang.String name) + +
+           
+ intSmbRandomAccessFile.read() + +
+           
+ intSmbRandomAccessFile.read(byte[] b) + +
+           
+ intSmbRandomAccessFile.read(byte[] b, + int off, + int len) + +
+           
+ voidSmbRandomAccessFile.readFully(byte[] b) + +
+           
+ voidSmbRandomAccessFile.readFully(byte[] b, + int off, + int len) + +
+           
+ intSmbRandomAccessFile.skipBytes(int n) + +
+           
+ voidSmbRandomAccessFile.write(int b) + +
+           
+ voidSmbRandomAccessFile.write(byte[] b) + +
+           
+ voidSmbRandomAccessFile.write(byte[] b, + int off, + int len) + +
+           
+ longSmbRandomAccessFile.getFilePointer() + +
+           
+ voidSmbRandomAccessFile.seek(long pos) + +
+           
+ longSmbRandomAccessFile.length() + +
+           
+ voidSmbRandomAccessFile.setLength(long newLength) + +
+           
+ voidSmbRandomAccessFile.close() + +
+           
+ booleanSmbRandomAccessFile.readBoolean() + +
+           
+ byteSmbRandomAccessFile.readByte() + +
+           
+ intSmbRandomAccessFile.readUnsignedByte() + +
+           
+ shortSmbRandomAccessFile.readShort() + +
+           
+ intSmbRandomAccessFile.readUnsignedShort() + +
+           
+ charSmbRandomAccessFile.readChar() + +
+           
+ intSmbRandomAccessFile.readInt() + +
+           
+ longSmbRandomAccessFile.readLong() + +
+           
+ floatSmbRandomAccessFile.readFloat() + +
+           
+ doubleSmbRandomAccessFile.readDouble() + +
+           
+ java.lang.StringSmbRandomAccessFile.readLine() + +
+           
+ java.lang.StringSmbRandomAccessFile.readUTF() + +
+           
+ voidSmbRandomAccessFile.writeBoolean(boolean v) + +
+           
+ voidSmbRandomAccessFile.writeByte(int v) + +
+           
+ voidSmbRandomAccessFile.writeShort(int v) + +
+           
+ voidSmbRandomAccessFile.writeChar(int v) + +
+           
+ voidSmbRandomAccessFile.writeInt(int v) + +
+           
+ voidSmbRandomAccessFile.writeLong(long v) + +
+           
+ voidSmbRandomAccessFile.writeFloat(float v) + +
+           
+ voidSmbRandomAccessFile.writeDouble(double v) + +
+           
+ voidSmbRandomAccessFile.writeBytes(java.lang.String s) + +
+           
+ voidSmbRandomAccessFile.writeChars(java.lang.String s) + +
+           
+ voidSmbRandomAccessFile.writeUTF(java.lang.String str) + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Constructors in jcifs.smb that throw SmbException
SID(java.lang.String textual) + +
+          Construct a SID from it's textual representation such as + S-1-5-21-1496946806-2192648263-3843101252-1029.
SmbFileInputStream(java.lang.String url) + +
+          Creates an InputStream for reading bytes from a file on + an SMB server addressed by the url parameter.
SmbFileInputStream(SmbFile file) + +
+          Creates an InputStream for reading bytes from a file on + an SMB server represented by the SmbFile parameter.
SmbFileOutputStream(java.lang.String url) + +
+          Creates an OutputStream for writing to a file + on an SMB server addressed by the URL parameter.
SmbFileOutputStream(SmbFile file) + +
+          Creates an OutputStream for writing bytes to a file on + an SMB server represented by the SmbFile parameter.
SmbFileOutputStream(java.lang.String url, + boolean append) + +
+          Creates an OutputStream for writing bytes to a file on an + SMB server addressed by the URL parameter.
SmbFileOutputStream(SmbFile file, + boolean append) + +
+          Creates an OutputStream for writing bytes to a file + on an SMB server addressed by the SmbFile parameter.
SmbFileOutputStream(java.lang.String url, + int shareAccess) + +
+          Creates an OutputStream for writing bytes to a file + on an SMB server addressed by the SmbFile parameter.
SmbRandomAccessFile(java.lang.String url, + java.lang.String mode, + int shareAccess) + +
+           
SmbRandomAccessFile(SmbFile file, + java.lang.String mode) + +
+           
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SmbFile.html b/docs/api/jcifs/smb/class-use/SmbFile.html new file mode 100644 index 0000000..ae0ec38 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SmbFile.html @@ -0,0 +1,321 @@ + + + + + + +Uses of Class jcifs.smb.SmbFile (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.SmbFile

+
+ + + + + + + + + +
+Packages that use SmbFile
jcifs.smb  
+  +

+ + + + + +
+Uses of SmbFile in jcifs.smb
+  +

+ + + + + + + + + +
Subclasses of SmbFile in jcifs.smb
+ classSmbNamedPipe + +
+          This class will allow a Java program to read and write data to Named + Pipes and Transact NamedPipes.
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in jcifs.smb that return SmbFile
+ SmbFile[]SmbFile.listFiles() + +
+          List the contents of this SMB resource as an array of + SmbFile objects.
+ SmbFile[]SmbFile.listFiles(java.lang.String wildcard) + +
+          The CIFS protocol provides for DOS "wildcards" to be used as + a performance enhancement.
+ SmbFile[]SmbFile.listFiles(SmbFilenameFilter filter) + +
+          List the contents of this SMB resource.
+ SmbFile[]SmbFile.listFiles(SmbFileFilter filter) + +
+          List the contents of this SMB resource.
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in jcifs.smb with parameters of type SmbFile
+ booleanDosFileFilter.accept(SmbFile file) + +
+           
+ voidSmbFile.renameTo(SmbFile dest) + +
+          Changes the name of the file this SmbFile represents to the name + designated by the SmbFile argument.
+ voidSmbFile.copyTo(SmbFile dest) + +
+          This method will copy the file or directory represented by this + SmbFile and it's sub-contents to the location specified by the + dest parameter.
+ booleanSmbFileFilter.accept(SmbFile file) + +
+           
+ booleanSmbFilenameFilter.accept(SmbFile dir, + java.lang.String name) + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + + + +
Constructors in jcifs.smb with parameters of type SmbFile
SmbFile(SmbFile context, + java.lang.String name) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFile(SmbFile context, + java.lang.String name, + int shareAccess) + +
+          Constructs an SmbFile representing a resource on an SMB network such + as a file or directory.
SmbFileInputStream(SmbFile file) + +
+          Creates an InputStream for reading bytes from a file on + an SMB server represented by the SmbFile parameter.
SmbFileOutputStream(SmbFile file) + +
+          Creates an OutputStream for writing bytes to a file on + an SMB server represented by the SmbFile parameter.
SmbFileOutputStream(SmbFile file, + boolean append) + +
+          Creates an OutputStream for writing bytes to a file + on an SMB server addressed by the SmbFile parameter.
SmbRandomAccessFile(SmbFile file, + java.lang.String mode) + +
+           
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SmbFileFilter.html b/docs/api/jcifs/smb/class-use/SmbFileFilter.html new file mode 100644 index 0000000..67125dd --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SmbFileFilter.html @@ -0,0 +1,188 @@ + + + + + + +Uses of Interface jcifs.smb.SmbFileFilter (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
jcifs.smb.SmbFileFilter

+
+ + + + + + + + + +
+Packages that use SmbFileFilter
jcifs.smb  
+  +

+ + + + + +
+Uses of SmbFileFilter in jcifs.smb
+  +

+ + + + + + + + + +
Classes in jcifs.smb that implement SmbFileFilter
+ classDosFileFilter + +
+           
+  +

+ + + + + + + + + +
Methods in jcifs.smb with parameters of type SmbFileFilter
+ SmbFile[]SmbFile.listFiles(SmbFileFilter filter) + +
+          List the contents of this SMB resource.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SmbFileInputStream.html b/docs/api/jcifs/smb/class-use/SmbFileInputStream.html new file mode 100644 index 0000000..8b585ec --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SmbFileInputStream.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.smb.SmbFileInputStream (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.SmbFileInputStream

+
+No usage of jcifs.smb.SmbFileInputStream +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SmbFileOutputStream.html b/docs/api/jcifs/smb/class-use/SmbFileOutputStream.html new file mode 100644 index 0000000..0b1f9b7 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SmbFileOutputStream.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.smb.SmbFileOutputStream (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.SmbFileOutputStream

+
+No usage of jcifs.smb.SmbFileOutputStream +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SmbFilenameFilter.html b/docs/api/jcifs/smb/class-use/SmbFilenameFilter.html new file mode 100644 index 0000000..9bc45d9 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SmbFilenameFilter.html @@ -0,0 +1,180 @@ + + + + + + +Uses of Interface jcifs.smb.SmbFilenameFilter (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
jcifs.smb.SmbFilenameFilter

+
+ + + + + + + + + +
+Packages that use SmbFilenameFilter
jcifs.smb  
+  +

+ + + + + +
+Uses of SmbFilenameFilter in jcifs.smb
+  +

+ + + + + + + + + + + + + +
Methods in jcifs.smb with parameters of type SmbFilenameFilter
+ java.lang.String[]SmbFile.list(SmbFilenameFilter filter) + +
+          List the contents of this SMB resource.
+ SmbFile[]SmbFile.listFiles(SmbFilenameFilter filter) + +
+          List the contents of this SMB resource.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SmbNamedPipe.html b/docs/api/jcifs/smb/class-use/SmbNamedPipe.html new file mode 100644 index 0000000..ffbd1c7 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SmbNamedPipe.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.smb.SmbNamedPipe (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.SmbNamedPipe

+
+No usage of jcifs.smb.SmbNamedPipe +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/class-use/SmbRandomAccessFile.html b/docs/api/jcifs/smb/class-use/SmbRandomAccessFile.html new file mode 100644 index 0000000..7225445 --- /dev/null +++ b/docs/api/jcifs/smb/class-use/SmbRandomAccessFile.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.smb.SmbRandomAccessFile (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.smb.SmbRandomAccessFile

+
+No usage of jcifs.smb.SmbRandomAccessFile +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/package-frame.html b/docs/api/jcifs/smb/package-frame.html new file mode 100644 index 0000000..be5efd0 --- /dev/null +++ b/docs/api/jcifs/smb/package-frame.html @@ -0,0 +1,78 @@ + + + + + + +jcifs.smb (JCIFS API) + + + + + + + + + + + +jcifs.smb + + + + +
+Interfaces  + +
+SmbFileFilter +
+SmbFilenameFilter
+ + + + + + +
+Classes  + +
+ACE +
+DosFileFilter +
+NtlmAuthenticator +
+NtlmContext +
+NtlmPasswordAuthentication +
+SID +
+SmbFile +
+SmbFileInputStream +
+SmbFileOutputStream +
+SmbNamedPipe +
+SmbRandomAccessFile
+ + + + + + +
+Exceptions  + +
+SmbAuthException +
+SmbException
+ + + + diff --git a/docs/api/jcifs/smb/package-summary.html b/docs/api/jcifs/smb/package-summary.html new file mode 100644 index 0000000..f091aa5 --- /dev/null +++ b/docs/api/jcifs/smb/package-summary.html @@ -0,0 +1,229 @@ + + + + + + +jcifs.smb (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package jcifs.smb +

+ + + + + + + + + + + + + +
+Interface Summary
SmbFileFilter 
SmbFilenameFilter 
+  + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Class Summary
ACEAn Access Control Entry (ACE) is an element in a security descriptor + such as those associated with files and directories.
DosFileFilter 
NtlmAuthenticatorThis class can be extended by applications that wish to trap authentication related exceptions and automatically retry the exceptional operation with different credentials.
NtlmContextFor initiating NTLM authentication (including NTLMv2).
NtlmPasswordAuthenticationThis class stores and encrypts NTLM user credentials.
SIDA Windows SID is a numeric identifier used to represent Windows + accounts.
SmbFileThis class represents a resource on an SMB network.
SmbFileInputStreamThis InputStream can read bytes from a file on an SMB file server.
SmbFileOutputStreamThis OutputStream can write bytes to a file on an SMB file server.
SmbNamedPipeThis class will allow a Java program to read and write data to Named + Pipes and Transact NamedPipes.
SmbRandomAccessFile 
+  + +

+ + + + + + + + + + + + + +
+Exception Summary
SmbAuthExceptionThe SmbAuthException encapsulates the variety of + authentication related error codes returned by an SMB server.
SmbExceptionThere are hundreds of error codes that may be returned by a CIFS + server.
+  + +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/package-tree.html b/docs/api/jcifs/smb/package-tree.html new file mode 100644 index 0000000..3a7880d --- /dev/null +++ b/docs/api/jcifs/smb/package-tree.html @@ -0,0 +1,176 @@ + + + + + + +jcifs.smb Class Hierarchy (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package jcifs.smb +

+
+
+
Package Hierarchies:
All Packages
+
+

+Class Hierarchy +

+
    +
  • class java.lang.Object +
+

+Interface Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/smb/package-use.html b/docs/api/jcifs/smb/package-use.html new file mode 100644 index 0000000..aa664a5 --- /dev/null +++ b/docs/api/jcifs/smb/package-use.html @@ -0,0 +1,214 @@ + + + + + + +Uses of Package jcifs.smb (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
jcifs.smb

+
+ + + + + + + + + +
+Packages that use jcifs.smb
jcifs.smb  
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Classes in jcifs.smb used by jcifs.smb
ACE + +
+          An Access Control Entry (ACE) is an element in a security descriptor + such as those associated with files and directories.
NtlmAuthenticator + +
+          This class can be extended by applications that wish to trap authentication related exceptions and automatically retry the exceptional operation with different credentials.
NtlmPasswordAuthentication + +
+          This class stores and encrypts NTLM user credentials.
SID + +
+          A Windows SID is a numeric identifier used to represent Windows + accounts.
SmbAuthException + +
+          The SmbAuthException encapsulates the variety of + authentication related error codes returned by an SMB server.
SmbException + +
+          There are hundreds of error codes that may be returned by a CIFS + server.
SmbFile + +
+          This class represents a resource on an SMB network.
SmbFileFilter + +
+           
SmbFilenameFilter + +
+           
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/Base64.html b/docs/api/jcifs/util/Base64.html new file mode 100644 index 0000000..bbd1217 --- /dev/null +++ b/docs/api/jcifs/util/Base64.html @@ -0,0 +1,278 @@ + + + + + + +Base64 (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.util +
+Class Base64

+
+java.lang.Object
+  extended byjcifs.util.Base64
+
+
+
+
public class Base64
extends java.lang.Object
+ +

+


+ +

+ + + + + + + + + + + + + + + + +
+Constructor Summary
Base64() + +
+           
+  + + + + + + + + + + + + + + + +
+Method Summary
+static byte[]decode(java.lang.String string) + +
+          Decodes the supplied Base-64 encoded string.
+static java.lang.Stringencode(byte[] bytes) + +
+          Base-64 encodes the supplied block of data.
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+Base64

+
+public Base64()
+
+
+ + + + + + + + +
+Method Detail
+ +

+encode

+
+public static java.lang.String encode(byte[] bytes)
+
+
Base-64 encodes the supplied block of data. Line wrapping is not + applied on output. +

+

+
Parameters:
bytes - The block of data that is to be Base-64 encoded. +
Returns:
A String containing the encoded data.
+
+
+
+ +

+decode

+
+public static byte[] decode(java.lang.String string)
+
+
Decodes the supplied Base-64 encoded string. +

+

+
Parameters:
string - The Base-64 encoded string that is to be decoded. +
Returns:
A byte[] containing the decoded data block.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/HMACT64.html b/docs/api/jcifs/util/HMACT64.html new file mode 100644 index 0000000..318cfba --- /dev/null +++ b/docs/api/jcifs/util/HMACT64.html @@ -0,0 +1,418 @@ + + + + + + +HMACT64 (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.util +
+Class HMACT64

+
+java.lang.Object
+  extended byjava.security.MessageDigestSpi
+      extended byjava.security.MessageDigest
+          extended byjcifs.util.HMACT64
+
+
+
All Implemented Interfaces:
java.lang.Cloneable
+
+
+
+
public class HMACT64
extends java.security.MessageDigest
implements java.lang.Cloneable
+ +

+This is an implementation of the HMACT64 keyed hashing algorithm. + HMACT64 is defined by Luke Leighton as a modified HMAC-MD5 (RFC 2104) + in which the key is truncated at 64 bytes (rather than being hashed + via MD5). +

+ +

+


+ +

+ + + + + + + + + + + + + + + + +
+Constructor Summary
HMACT64(byte[] key) + +
+          Creates an HMACT64 instance which uses the given secret key material.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ java.lang.Objectclone() + +
+           
+protected  byte[]engineDigest() + +
+           
+protected  intengineDigest(byte[] buf, + int offset, + int len) + +
+           
+protected  intengineGetDigestLength() + +
+           
+protected  voidengineReset() + +
+           
+protected  voidengineUpdate(byte b) + +
+           
+protected  voidengineUpdate(byte[] input, + int offset, + int len) + +
+           
+ + + + + + + +
Methods inherited from class java.security.MessageDigest
digest, digest, digest, getAlgorithm, getDigestLength, getInstance, getInstance, getInstance, getProvider, isEqual, reset, toString, update, update, update
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+HMACT64

+
+public HMACT64(byte[] key)
+
+
Creates an HMACT64 instance which uses the given secret key material. +

+

Parameters:
key - The key material to use in hashing.
+ + + + + + + + +
+Method Detail
+ +

+clone

+
+public java.lang.Object clone()
+
+
+
+
+
+
+
+
+
+ +

+engineDigest

+
+protected byte[] engineDigest()
+
+
+
+
+
+
+
+
+
+ +

+engineDigest

+
+protected int engineDigest(byte[] buf,
+                           int offset,
+                           int len)
+
+
+
+
+
+
+
+
+
+ +

+engineGetDigestLength

+
+protected int engineGetDigestLength()
+
+
+
+
+
+
+
+
+
+ +

+engineReset

+
+protected void engineReset()
+
+
+
+
+
+
+
+
+
+ +

+engineUpdate

+
+protected void engineUpdate(byte b)
+
+
+
+
+
+
+
+
+
+ +

+engineUpdate

+
+protected void engineUpdate(byte[] input,
+                            int offset,
+                            int len)
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/LogStream.html b/docs/api/jcifs/util/LogStream.html new file mode 100644 index 0000000..3c0be5b --- /dev/null +++ b/docs/api/jcifs/util/LogStream.html @@ -0,0 +1,363 @@ + + + + + + +LogStream (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.util +
+Class LogStream

+
+java.lang.Object
+  extended byjava.io.OutputStream
+      extended byjava.io.FilterOutputStream
+          extended byjava.io.PrintStream
+              extended byjcifs.util.LogStream
+
+
+
+
public class LogStream
extends java.io.PrintStream
+ +

+0 - nothing +1 - critical [default] +2 - basic info can be logged under load +3 - almost everything +N - debugging +

+ +

+


+ +

+ + + + + + + + + + + + + + +
+Field Summary
+static intlevel + +
+           
+ + + + + + + +
Fields inherited from class java.io.FilterOutputStream
out
+  + + + + + + + + + + +
+Constructor Summary
LogStream(java.io.PrintStream stream) + +
+           
+  + + + + + + + + + + + + + + + + + + + +
+Method Summary
+static LogStreamgetInstance() + +
+           
+static voidsetInstance(java.io.PrintStream stream) + +
+          This must be called before getInstance is called or + it will have no effect.
+static voidsetLevel(int level) + +
+           
+ + + + + + + +
Methods inherited from class java.io.PrintStream
checkError, close, flush, print, print, print, print, print, print, print, print, print, println, println, println, println, println, println, println, println, println, println, setError, write, write
+ + + + + + + +
Methods inherited from class java.io.FilterOutputStream
write
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Field Detail
+ +

+level

+
+public static int level
+
+
+
+
+ + + + + + + + +
+Constructor Detail
+ +

+LogStream

+
+public LogStream(java.io.PrintStream stream)
+
+
+ + + + + + + + +
+Method Detail
+ +

+setLevel

+
+public static void setLevel(int level)
+
+
+
+
+
+
+ +

+setInstance

+
+public static void setInstance(java.io.PrintStream stream)
+
+
This must be called before getInstance is called or + it will have no effect. +

+

+
+
+
+
+ +

+getInstance

+
+public static LogStream getInstance()
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/RC4.html b/docs/api/jcifs/util/RC4.html new file mode 100644 index 0000000..31db710 --- /dev/null +++ b/docs/api/jcifs/util/RC4.html @@ -0,0 +1,297 @@ + + + + + + +RC4 (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +jcifs.util +
+Class RC4

+
+java.lang.Object
+  extended byjcifs.util.RC4
+
+
+
+
public class RC4
extends java.lang.Object
+ +

+


+ +

+ + + + + + + + + + + + + + + + + + + +
+Constructor Summary
RC4() + +
+           
RC4(byte[] key) + +
+           
+  + + + + + + + + + + + + + + + +
+Method Summary
+ voidinit(byte[] key, + int ki, + int klen) + +
+           
+ voidupdate(byte[] src, + int soff, + int slen, + byte[] dst, + int doff) + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + + + + +
+Constructor Detail
+ +

+RC4

+
+public RC4()
+
+
+
+ +

+RC4

+
+public RC4(byte[] key)
+
+
+ + + + + + + + +
+Method Detail
+ +

+init

+
+public void init(byte[] key,
+                 int ki,
+                 int klen)
+
+
+
+
+
+
+ +

+update

+
+public void update(byte[] src,
+                   int soff,
+                   int slen,
+                   byte[] dst,
+                   int doff)
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/class-use/Base64.html b/docs/api/jcifs/util/class-use/Base64.html new file mode 100644 index 0000000..afec12b --- /dev/null +++ b/docs/api/jcifs/util/class-use/Base64.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.util.Base64 (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.util.Base64

+
+No usage of jcifs.util.Base64 +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/class-use/HMACT64.html b/docs/api/jcifs/util/class-use/HMACT64.html new file mode 100644 index 0000000..6f8b559 --- /dev/null +++ b/docs/api/jcifs/util/class-use/HMACT64.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.util.HMACT64 (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.util.HMACT64

+
+No usage of jcifs.util.HMACT64 +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/class-use/LogStream.html b/docs/api/jcifs/util/class-use/LogStream.html new file mode 100644 index 0000000..1ad90a2 --- /dev/null +++ b/docs/api/jcifs/util/class-use/LogStream.html @@ -0,0 +1,172 @@ + + + + + + +Uses of Class jcifs.util.LogStream (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.util.LogStream

+
+ + + + + + + + + +
+Packages that use LogStream
jcifs.util  
+  +

+ + + + + +
+Uses of LogStream in jcifs.util
+  +

+ + + + + + + + + +
Methods in jcifs.util that return LogStream
+static LogStreamLogStream.getInstance() + +
+           
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/class-use/RC4.html b/docs/api/jcifs/util/class-use/RC4.html new file mode 100644 index 0000000..9c24db9 --- /dev/null +++ b/docs/api/jcifs/util/class-use/RC4.html @@ -0,0 +1,136 @@ + + + + + + +Uses of Class jcifs.util.RC4 (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
jcifs.util.RC4

+
+No usage of jcifs.util.RC4 +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/package-frame.html b/docs/api/jcifs/util/package-frame.html new file mode 100644 index 0000000..03bacfd --- /dev/null +++ b/docs/api/jcifs/util/package-frame.html @@ -0,0 +1,38 @@ + + + + + + +jcifs.util (JCIFS API) + + + + + + + + + + + +jcifs.util + + + + +
+Classes  + +
+Base64 +
+HMACT64 +
+LogStream +
+RC4
+ + + + diff --git a/docs/api/jcifs/util/package-summary.html b/docs/api/jcifs/util/package-summary.html new file mode 100644 index 0000000..dea115d --- /dev/null +++ b/docs/api/jcifs/util/package-summary.html @@ -0,0 +1,164 @@ + + + + + + +jcifs.util (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package jcifs.util +

+ + + + + + + + + + + + + + + + + + + + + +
+Class Summary
Base64 
HMACT64This is an implementation of the HMACT64 keyed hashing algorithm.
LogStream0 - nothing +1 - critical [default] +2 - basic info can be logged under load +3 - almost everything +N - debugging
RC4 
+  + +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/package-tree.html b/docs/api/jcifs/util/package-tree.html new file mode 100644 index 0000000..a7e839a --- /dev/null +++ b/docs/api/jcifs/util/package-tree.html @@ -0,0 +1,156 @@ + + + + + + +jcifs.util Class Hierarchy (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package jcifs.util +

+
+
+
Package Hierarchies:
All Packages
+
+

+Class Hierarchy +

+
    +
  • class java.lang.Object
      +
    • class jcifs.util.Base64
    • class java.security.MessageDigestSpi
        +
      • class java.security.MessageDigest
          +
        • class jcifs.util.HMACT64 (implements java.lang.Cloneable) +
        +
      +
    • class java.io.OutputStream
        +
      • class java.io.FilterOutputStream
          +
        • class java.io.PrintStream +
        +
      +
    • class jcifs.util.RC4
    +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/jcifs/util/package-use.html b/docs/api/jcifs/util/package-use.html new file mode 100644 index 0000000..44cfb8e --- /dev/null +++ b/docs/api/jcifs/util/package-use.html @@ -0,0 +1,166 @@ + + + + + + +Uses of Package jcifs.util (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
jcifs.util

+
+ + + + + + + + + +
+Packages that use jcifs.util
jcifs.util  
+  +

+ + + + + + + + +
+Classes in jcifs.util used by jcifs.util
LogStream + +
+          0 - nothing +1 - critical [default] +2 - basic info can be logged under load +3 - almost everything +N - debugging
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/overview-frame.html b/docs/api/overview-frame.html new file mode 100644 index 0000000..d17150f --- /dev/null +++ b/docs/api/overview-frame.html @@ -0,0 +1,48 @@ + + + + + + +Overview (JCIFS API) + + + + + + + + + + + + + + + +
+
+ + + + + +
All Classes +

+ +Packages +
+jcifs +
+jcifs.netbios +
+jcifs.smb +
+jcifs.util +
+

+ +

+  + + diff --git a/docs/api/overview-summary.html b/docs/api/overview-summary.html new file mode 100644 index 0000000..19e2989 --- /dev/null +++ b/docs/api/overview-summary.html @@ -0,0 +1,526 @@ + + + + + + +Overview (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +


+ + +

+See: +
+          Description +

+ + + + + + + + + + + + + + + + + + + + + +
+Packages
jcifs 
jcifs.netbios 
jcifs.smb 
jcifs.util 
+ +

+

+

+

JCIFS
+The Java CIFS Client Library

+http://jcifs.samba.org/
+

+ +

The JCIFS SMB client library enables Java applications to remotely +access shared files and directories on SMB file servers(i.e. +a Microsoft Windows "share") in addition to domain, workgroup, and +server enumeration of NetBIOS over TCP/IP networks. It is an advanced +implementation of the CIFS protocol supporting Unicode, batching, +multiplexing of threaded callers, encrypted authentication, transactions, +the Remote Access Protocol (RAP), and much more. It is licensed under +LGPL which means commercial organizations can legitimately use it with +their proprietary code(you just can't sell or give away a modified binary +only version of the library itself without reciprocation). + +

The API
+ +

The SmbFile, SmbFileInputStream +, and SmbFileOutputStream classes are analogous +to the File, FileInputStream, and +FileOutputStream classes so if you know how to use +those it should be quite obvious how to use jCIFS provided you set any +necessary properties (i.e. a WINS server) and understand the +smb:// URL syntax. + +

Here's an example to retrieve a file: + +

+import jcifs.smb.*;
+
+jcifs.Config.setProperty( "jcifs.netbios.wins", "192.168.1.220" );
+NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domain", "username", "password");
+SmbFileInputStream in = new SmbFileInputStream("smb://host/c/My Documents/somefile.txt", auth);
+byte[] b = new byte[8192];
+int n;
+while(( n = in.read( b )) > 0 ) {
+    System.out.write( b, 0, n );
+}
+
+ +

You can also read/write, delete, make directories, rename, list +contents of a directory, list the workgroups/ntdomains and servers on +the network, list the shares of a server, open named pipes, authenticate +web clients ...etc. + + +

+Setting Client Properties
+ +

It may be necessary to set various properties for the client to +function properly. For example, to connect to a server on a remote +subnet the IP address of a WINS server is +required to retrieve the target address although DNS names and direct +IP addresses are also valid server components within an SMB URL. + +

There are three ways to specify any of the available properties listed +the table at the bottom of this page. + +

    +
  • The traditional System properties are read when the client is first +used. This means you can specify an individual property (the full property +name) on the command line like: + +

    +$ java -Djcifs.netbios.wins=192.168.1.220 MyApp
    +
    + +

    OR set a System property from within your application before +any jCIFS classes are instantiated like: + +

    +System.setProperty( "jcifs.netbios.wins", "192.168.1.220" );
    +
    + +
  • OR use the jcifs.Config class which is the class that +maintains this information internally however, again, properties must +be set before jCIFS client classes are referenced: + +

    +jcifs.Config.setProperty( "jcifs.netbios.wins", "192.168.1.220" );
    +
    + +
  • OR if the property "jcifs.properties" defines the location of a properties file, all properties will be loaded from it. For example: + +

    +$ cat miallen.prp
    +jcifs.netbios.wins=192.168.1.220
    +jcifs.smb.client.username=miallen
    +jcifs.smb.client.password=legos56
    +;jcifs.netbios.baddr=192.168.1.255
    +;jcifs.util.loglevel = 10
    +$ java -Djcifs.properties=miallen.prp MyApp
    +
    + +
+ +

Any properties specified using the -Djcifs.properties=myjcifsproperties.prp file may be overridden using the System properties as will any -Dfull.property.name=value VM parameters which in turn may then be overridden by the direct manipulation of properties using the Config class. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Available Properties
+These properties may need to be specified for correct operation
jcifs.smb.client.username +The default username used if not specified in an SMB URL +
jcifs.smb.client.password +The default password used if not specified in an SMB URL +
jcifs.smb.client.domain +The default authentication domain used if not specified in an SMB URL +
jcifs.netbios.wins +The IP address of the WINS server. This is only required when accessing hosts on different subnets although it is recomended if a WINS server is provided. +
jcifs.netbios.baddr +The local network's broadcast address. It may be necessary to set this for certain network configurations because the default of 255.255.255.255 may otherwise throw a "Network is unreachable" IOException. For example if the local host's IP address is 192.168.1.15, the broadcast address would likely be 192.168.1.255. +
jcifs.netbios.scope +This is extremely rare but NetBIOS provides for a "scope id" to be used in a attempt to conceal groups of machines on the same network. Ask your network administrator if scope id is used. If so, it must be set using this property or name queries will fail. +
jcifs.smb.client.laddr +The IP address of the local interface the client should bind to if it is different from the default. For example if the client is to be used over a dial-up connection the IP address of the PPP interface may need to be specified with this property. +
jcifs.netbios.laddr +The IP address of the local interface the client should bind to for name queries if it is different from the default. +
jcifs.netbios.lmhosts +The path to an lmhosts file containing a map of IP addresses to hostnames. The format of this file is identical to that of the Windows lmhosts file format. +See Setting Name Resoultion Properties for details. +
jcifs.smb.client.disablePlainTextPasswords +Plain text passwords should never be used and are disabled by default. To enable jCIFS to use plain text password this property must be set to false. +
jcifs.encoding +If the locale character encoding of the target server is not MS-DOS Latin-1, this property needs to be changed to reflect the proper encoding (e.g. Cp866 for Russian). Otherwise, share names, passwords, and in some cases file and directory names that contain non ASCII characters may not be handled properly. See this list of Supported Encodings and concentrate on the ones attributed as MS-DOS encodings. By default this property is Cp860 which is MS-DOS Latin1. +

+Note: The Cp860 charset converter is located in jre/lib/charsets.jar which AFAIK is only supported by the internationalized version of Sun's JRE. If Cp860 is not available an exception will occur. To avoid this exception you can set jcifs.encoding to ASCII but share names and passwords with non-ASCII characters will not be processed correctly. To determine if jCIFS is properly processing these characters create a share that contains non-ASCII characers (e.g. Grüße) and then try to list that share with the ListFiles.java example program. +

+As of jcifs-1.2.8 this property no longer defaults to the file.encoding system property because it was almost always meaningless (e.g. usually it's UTF-8 on Linux and no CIFS server currently emits UTF-8). +

jcifs.smb.client.useExtendedSecurityTrue by default but this must be set to false for Samba 3.0.x as it seems older versions of Samba do not support *raw* NTLMSSP and currently JCIFS does not support SPNEGO.
Less Commonly Used Properties
+These properties are not required for the client to function but may be necessary for optimal utility
jcifs.resolveOrder +A comma separated list of name resolution method identifiers that specify which methods will be used and in what order to resolve hostnames. The possible identifiers in default order are LMHOSTS, WINS, BCAST, and DNS. +See Setting Name Resoultion Properties for details. +
jcifs.util.loglevel +An integer specifying the verbosity of log messages. Higher values are more verbose +
    +
  • 0 - No log messages are printed -- not even crticial exceptions.
  • +
  • 1 - The default level. Only critical messages are logged.
  • +
  • 2 - Hightened log messages suitable for logging while under load.
  • +
  • 3 - Almost everything.
  • +
  • N - Debugging only.
  • +
+
jcifs.util.log +Removed This property has been replaced by the above jcifs.util.loglevel property. +A series of string identifiers to induce log messages to be printed to the console such as log=EXC,DEB,WAR,HEX would log internal exceptions, debugging, warnings, and hex dumps of network packets. ALL may be specified to indicate all messages should be logged. The ALL argument will produce more messages than EXC,DEB,WAR,HEX combined. NON will not print anything to the console including exceptions. +
jcifs.smb.client.attrExpirationPeriod +Attributes of a file are cached for attrExpirationPeriod milliseconds. The default is 5000. This greatly improves performance because it eliminates redundant calls to the server however it is possible that two separate instances of SmbFiles pointing to the same resource may produce different results in awkward situations (e.g. s1.canRead() may return true even though s2.delete() was called immediately before). For maximum reliability, turn off attribute expiration by setting this property to 0. +
jcifs.smb.client.responseTimeout +The time period in milliseconds that the client will wait for a response to a request from the server. The default value is 30000. Under poor network conditions you may wish to increase this value but jcifs.smb.client.soTimeout should be increased as well to accommodate. +
jcifs.smb.client.soTimeout +To prevent the client from holding server resources unnecessarily, sockets are closed after this time period if there is no activity. This time is specified in milliseconds. The default is 35000. +
jcifs.netbios.cachePolicy +When a NetBIOS name is resolved with the NbtAddress class it is cached to reduce redundant name queries. This property controls how long, in seconds, these names are cached. The default is 30 seconds, 0 is no caching, and -1 is forever. +
jcifs.netbios.hostname +This property will force port 139 rather than the default port 445. Normally a CIFS client connecting to port 139 must present a NetBIOS name for itself to the server. JCIFS dynamically generates a name (e.g. JCIFS35_177_E6) for this purpose however it may be desirable to set this property to a specific name(e.g. PROD_FEED3) for reasons such as server accounting purposes. + +
jcifs.smb.client.listSize +One command that may be individually tuned is the TRANS2_FIND_FIRST/NEXT2 operation. It is provoked by the list() method of SmbFile (but not for smb://, smb://workgroup/, or smb://server/ URLs). The size of the data buffer used, in bytes, can be set with this property. The default size is 65535 bytes. On higher latency networks a value below the MTU (e.g. 1200) may result in better performance. + +
jcifs.smb.client.listCount +Similar to listSize property above, listCount is for tuning the TRANS2_FIND_FIRST/NEXT2 operation. It controls the maximum number of directory and file entries that should be returned with each request. The default is 200. On higher latency networks a lowever value (e.g. 15) may result in better performance. + +
jcifs.smb.client.lport +If a particular local port must be used for socket communications, perhaps because a firewall requires the source port to be a specific value, it can be set with this property(e.g. lport=5139). This has no effect on the remote port which is invariably 139. +
jcifs.netbios.soTimeout +To prevent the client from holding resources unnecessarily, the datagram socket used for nameservice queries is closed after this time period which is specified in milliseconds. The default is 5000. + +
jcifs.netbios.lport +If a particular local port must be used for socket communications, perhaps because a firewall requires the source port to be a specific value, it can be set with this property(e.g. lport=5137). This has no effect on the remote port which is invariably 137. +
jcifs.netbios.retryCount +The number of times a name query should be attempted if no answer is received. In adverse network conditions one may wish to increase this value however failed name queries take retryCount * retryDuration milliseconds. The default value is 2. Should probably increase jcifs.netbios.retryTimeout instead. +
jcifs.netbios.retryTimeout +The duration in milliseconds that the client will wait for a response to a name query. The default is 3000. +
jcifs.http.domainController +The DNS hostname or IP address of a server that should be used to authenticate HTTP clients with the NtlmSsp class (use by NtlmHttpFilter and NetworkExplorer). If this is not specified the jcifs.smb.client.domain 0x1C NetBIOS group name will be queried. It is not necessary for this to specify a real domain controller. The IP address of a workstation will do for development purposes. We do not support DCE/RPC NETLOGON. +See jCIFS NTLM HTTP Authentication Support for more information. +
jcifs.http.basicRelm +The realm for basic authentication. This property defaults to 'jCIFS'. +
jcifs.http.enableBasic +Setting this property to true enables basic authentication over HTTPS only. +
jcifs.http.insecureBasic +Setting this property to true enables basic authentication over plain HTTP. This configuration passes user credentials in plain text over the network. It should not be used in environment where security is required. +
jcifs.smb.lmCompatibility +This client can perform NTLMv2 with and without NTLMSSP as well as NTLMv1. The default lmCompatibility level is 3 to indicate that NTLMv2 should be favored (although prior to JCIFS 1.3.0, NTLMv1 was the default). This can be changed by using this property with an integer that specifies the "level" of security: +
    +
  • 0,1 -- Sends LM and NTLM responses. +
  • 2 -- Sends only the NTLM response. This is more secure than Levels 0 and 1, because it eliminates the cryptographically-weak LM response. +
  • 3,4,5 -- Sends LMv2 and NTLMv2 data. NTLMv2 session security is also negotiated if the server supports it. This is the default behavior (in 1.3.0 or later). +
+These values mirror those used with the Windows registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa used for the same purpose. See the page entitled The NTLM Authentication Protocol for a technical description of these authentication mechanisms. +

+This must be set to 0 for older versions of Samba (3.0.x) as it seems they do not support *raw* NTLMSSP and currently JCIFS does not support SPNEGO. +

jcifs.smb.client.ssnLimit +No more than this number of sessions will be open over the same transport. If the limit is reached, new redundant transports will be opened to accomodate more sessions. If this value is set to 1 a new transport will be created for each session. The default value is 250. Using a value that is too high may result in ERRSVR/90: Too many Uids active on this session. +
jcifs.smb.client.signingPreferred +The JCIFS client will negotiate SMB signing with a server that requires it. If the server does not require SMB signing but supports it, it will be necessary to set this property to true for signing to occur. Signing is required by default with Windows 2003. Currently it is not possible to use singing with NTLM HTTP authentication because the password hases are required to generate the signing key which is known only to the client (Internet Exploiter). It will be necessary to implement the NETLOGON RPC to fully support signing with NTLM HTTP authentication. We do not support DCE/RPC NETLOGON. +
jcifs.http.loadBalance +If a jcifs.smb.client.domain property is specified (and domainController is not specified) the NtlmHttpFilter will query for domain controllers by name. If this property is true the Filter will rotate through the list of domain controllers when authenticating users. The default value is true. The jcifs.netbios.lookupRespLimit property can also be used to limit the number of domain controllers used. +
jcifs.netbios.lookupRespLimit +The 0x1C NetBIOS name query returns a list of domain controllers. It is believed that the servers at the top of this list should be favored. This property limits the range of servers returned by name queries. The default value is 5 meaning the top 5 domain controllers will be used. +
jcifs.smb.client.logonShare +The shared name against which SmbSession.logon() will authenticate users. The default value is IPC$ but changing it can be used to create simple group based access control for the NtlmHttpFilter or other applications that use SmbSession.logon(). See the SmbSession API documentation for details. +
jcifs.smb.client.dfs.disabled +If this property is true, domain based DFS referrals will be disabled. The default value is false. This property can be important in non-domain environments where domain-based DFS referrals that normally run when JCIFS first tries to resolve a path would timeout causing a long startup delay (e.g. running JCIFS only on the local machine without a network like on a laptop). +
jcifs.smb.client.dfs.ttl +The time in seconds that DFS topology information should be cached. The default value is 300 seconds (although the trusted domains list is cached for 10 times jcifs.smb.client.dfs.ttl). +
jcifs.smb.client.dfs.strictView +This property controls how JCIFS behaves if it fails to enumerate DFS roots but succeeds to enumerate shares. By default this value is false to indicate that JCIFS should quitely return the list of shares even if the DFS root enumeration fails. If this value is set to true, an exception will be thrown if DFS information cannot be successfully retrieved (e.g. an SmbAuthException due to insufficient access). +
Advanced Properties
+These should not be changed
jcifs.smb.client.nativeOs +Specifies the NativeOS field in the SMB_COM_SESSION_SETUP_ANDX command. The default is the os.name system property. +
jcifs.smb.client.nativeLanMan +Specifies the NativeLanMan field in the SMB_COM_SESSION_SETUP_ANDX request. The default is "jCIFS". +
jcifs.smb.client.maxMpxCount +This client can send and receive messages concurrently over the same socket. The number of simultaneous outstanding transactions with a given server is controlled by this property. The default is 10. Under extremely unlikely circumstances this value may need to be adjusted to achive optimal throughput. It is more likely this property would be set to 1 to support a deficient server. +
jcifs.smb.client.useNTSmbs +This property is largely ignored. +
jcifs.smb.client.useUnicode +This client will use Unicode strings wherever negotiated. Setting this property to false will remove Unicode capability and therefore use only 8 bit strings will used (although Unicode will still be used to accomodate a few protocol bugs). +
jcifs.netbios.client.writeSize +The size of buffer in bytes that the NetBIOS Socket layer uses to write data to the raw socket. The default is 1500 and in effect limits the NetBIOS session service outbound message size. +
jcifs.smb.client.flags2 +A carefully crafted integer may be used with this property to specify the flags2 field of the SMB header. +
jcifs.smb.client.capabilities +A carefully crafted integer may be used with this property to specify the capabilities field of the SMB_COM_SESSION_SETUP_ANDX command. +
jcifs.smb.client.rcv_buf_size +One buffer is used to decode incoming packets. The size of this buffer may be specified, in bytes, using this property. The default is 60416. +
jcifs.smb.client.snd_buf_size +One buffer is used to encode outgoing packets. The size of this buffer may be specified, in bytes, using this property. The default is 16644. +
jcifs.smb.client.serviceType +The service type should always be '?????' which means that the server should resolve it and to my knowledge this resolution mechanism has never failed. But ... should one wish to experiment you can set it with this property. Service types can be at least A:, LPT1:, IPC, and COMM. +
jcifs.smb.client.<smb_ident>.<smb_ident> +It is possible to "tune" batching (a.k.a chaining) by specifying and integer batch level for a pair of SMB messages. See Batching for details. +
jcifs.smb.client.useBatching +To turn off batching altogether specify false for this property. The default is true. +
jcifs.smb.client.tcpNoDelay +If this property is true, setTcpNoDelay( true ) will be called on all SMB transport sockets. The default value is false (Nagle's algorithm is enabled). +
jcifs.smb.client.transaction_buf_size +The maximum SMB transaction buffer size. The default is 0xFFFF - 512. +
jcifs.smb.maxBuffers +The maximum number of of jcifs.smb.client.transaction_buf_size buffers that the buffer cache will create. The default is 16. +
+

+ +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/overview-tree.html b/docs/api/overview-tree.html new file mode 100644 index 0000000..bc8b44f --- /dev/null +++ b/docs/api/overview-tree.html @@ -0,0 +1,184 @@ + + + + + + +Class Hierarchy (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For All Packages

+
+
+
Package Hierarchies:
jcifs, jcifs.netbios, jcifs.smb, jcifs.util
+
+

+Class Hierarchy +

+
    +
  • class java.lang.Object
      +
    • class jcifs.smb.ACE
    • class jcifs.util.Base64
    • class jcifs.Config
    • class jcifs.smb.DosFileFilter (implements jcifs.smb.SmbFileFilter) +
    • class java.io.InputStream +
    • class java.security.MessageDigestSpi
        +
      • class java.security.MessageDigest
          +
        • class jcifs.util.HMACT64 (implements java.lang.Cloneable) +
        +
      +
    • class jcifs.netbios.NbtAddress
    • class jcifs.dcerpc.ndr.NdrObject
        +
      • class jcifs.dcerpc.rpc.sid_t
          +
        • class jcifs.smb.SID
        +
      +
    • class jcifs.smb.NtlmAuthenticator
    • class jcifs.smb.NtlmContext
    • class jcifs.smb.NtlmPasswordAuthentication (implements java.security.Principal, java.io.Serializable) +
    • class java.io.OutputStream +
    • class jcifs.util.RC4
    • class jcifs.smb.SmbRandomAccessFile (implements java.io.DataInput, java.io.DataOutput) +
    • class java.lang.Throwable (implements java.io.Serializable) +
        +
      • class java.lang.Exception
          +
        • class java.io.IOException
            +
          • class jcifs.smb.SmbException (implements jcifs.smb.DosError, jcifs.smb.NtStatus, jcifs.smb.WinError) + +
          +
        +
      +
    • class jcifs.UniAddress
    • class java.net.URLConnection
        +
      • class jcifs.smb.SmbFile (implements jcifs.smb.SmbConstants) + +
      +
    +
+

+Interface Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/package-list b/docs/api/package-list new file mode 100644 index 0000000..9b9cbaf --- /dev/null +++ b/docs/api/package-list @@ -0,0 +1,4 @@ +jcifs +jcifs.netbios +jcifs.smb +jcifs.util diff --git a/docs/api/packages.html b/docs/api/packages.html new file mode 100644 index 0000000..864cb52 --- /dev/null +++ b/docs/api/packages.html @@ -0,0 +1,37 @@ + + + + + + + (JCIFS API) + + + + + + + + + + + +
+ +
+ +
+
+The front page has been relocated.Please see: +
+          Frame version +
+          Non-frame version.
+ + + diff --git a/docs/api/resources/inherit.gif b/docs/api/resources/inherit.gif new file mode 100644 index 0000000..c814867 Binary files /dev/null and b/docs/api/resources/inherit.gif differ diff --git a/docs/api/serialized-form.html b/docs/api/serialized-form.html new file mode 100644 index 0000000..7b03d8d --- /dev/null +++ b/docs/api/serialized-form.html @@ -0,0 +1,281 @@ + + + + + + +Serialized Form (JCIFS API) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Serialized Form

+
+ + + + + +
+Class jcifs.smb.NtlmPasswordAuthentication extends java.lang.Object implements Serializable
+ +

+ + + + + +
+Serialized Fields
+ +

+domain

+
+java.lang.String domain
+
+
+
+
+
+ +

+username

+
+java.lang.String username
+
+
+
+
+
+ +

+password

+
+java.lang.String password
+
+
+
+
+
+ +

+ansiHash

+
+byte[] ansiHash
+
+
+
+
+
+ +

+unicodeHash

+
+byte[] unicodeHash
+
+
+
+
+
+ +

+hashesExternal

+
+boolean hashesExternal
+
+
+
+
+
+ +

+clientChallenge

+
+byte[] clientChallenge
+
+
+
+
+
+ +

+challenge

+
+byte[] challenge
+
+
+
+
+ +

+


+ + + + + +
+Class jcifs.smb.SmbAuthException extends SmbException implements Serializable
+ +

+ +

+


+ + + + + +
+Class jcifs.smb.SmbException extends java.io.IOException implements Serializable
+ +

+ + + + + +
+Serialized Fields
+ +

+status

+
+int status
+
+
+
+
+
+ +

+rootCause

+
+java.lang.Throwable rootCause
+
+
+
+
+ +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/docs/api/stylesheet.css b/docs/api/stylesheet.css new file mode 100644 index 0000000..14c3737 --- /dev/null +++ b/docs/api/stylesheet.css @@ -0,0 +1,29 @@ +/* Javadoc style sheet */ + +/* Define colors, fonts and other style attributes here to override the defaults */ + +/* Page background color */ +body { background-color: #FFFFFF } + +/* Headings */ +h1 { font-size: 145% } + +/* Table colors */ +.TableHeadingColor { background: #CCCCFF } /* Dark mauve */ +.TableSubHeadingColor { background: #EEEEFF } /* Light mauve */ +.TableRowColor { background: #FFFFFF } /* White */ + +/* Font used in left-hand frame lists */ +.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif } +.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } +.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } + +/* Navigation bar fonts and colors */ +.NavBarCell1 { background-color:#EEEEFF;} /* Light mauve */ +.NavBarCell1Rev { background-color:#00008B;} /* Dark Blue */ +.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;} +.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;} + +.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} +.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} + diff --git a/docs/authhandler.html b/docs/authhandler.html new file mode 100644 index 0000000..2e2c17e --- /dev/null +++ b/docs/authhandler.html @@ -0,0 +1,202 @@ + + + + + + + + + +

JCIFS Exceptions and NtlmAuthenticator

+ +This document describes how jCIFS communicates server errors to callers and how authentication related exceptions may be handled differently from regular exceptions. How jCIFS can be used to authenticate arbitrary user credentials is not discussed although it is in the FAQ. + +

SmbException

+ +There are hundreds of error codes that may be returned by a CIFS server. It would be unacceptable to have an Exception class for each so the jCIFS client represents all of these using the SmbException class. The NT STATUS code for an SmbException may be retrieved using it's getNtStatus() method. +

+All of the methods of SmbFile that generate network IO can potentially throw an SmbException. Under normal operation it is not necessary to catch and interrogate each exception however this mechanism provides the developer with an opportunity to make an application more sophisticated and robust in the event of an error. Consider the following example: + +
+while( retry-- ) {
+    try {
+        ...
+        d = f.lastModified();
+        ...
+    } catch( SmbException se ) {
+        if( se.getNtStatus() == SmbException.NT_STATUS_DEVICE_NOT_READY ) {
+            // The tape drive is not ready yet, let's wait a little while
+            Thread.sleep( retryPeriod );
+        } else {
+            throw se;
+        }
+    }
+
+ +In this example (some kind of backup utility that accesses a shared tape drive perhaps) the developer knows that accessing this device will return an NT_STATUS_DEVICE_NOT_READY status code if the tape has not finished rewinding. The SmbException is caught and examined for this condition so that the program may sleep for a predefined amount of time while waiting for the drive to become ready. Otherwise exceptions with status codes other than NT_STATUS_DEVICE_NOT_READY are re-thrown. Adding this kind of support to your application usually requires some experimentation to determine what types of error codes will be returned by a server and in general the technique is not portable. + +

+ +The SmbException class has text messages associated with the more common status codes. The SmbExcption for NT_STATUS_DEVICE_NOT_READY will generate the familiar "The device is not ready" message you get when trying to access a CDROM drive without a disk in it. Of course not all of the various error codes have associated text messages and the ones that do are in English at the moment. + +

+ +Note: Eventually there may be a java.util.ResourceBundle to manage common text messages in various languages. + +

SmbAuthException

+ +One rather common not-so-exceptional set of exceptions are the authentication related exceptions. For example, if an ordinary user attempts to read a file which may only be accessed by a user with "Backup Operator" permissions, the server will return a status code of NT_STATUS_ACCESS_DENIED (at least NT with NTFS will). Similarly if the user is restricted to accessing a server during a prescribed time period, the server may return an NT_STATUS_INVALID_LOGON_HOURS status code. To catch these exceptions (perhaps to ask the user for alternative credentials), using only the mechanism described above, a switch block like the following would be necessary: + +
+switch( se.getNtStatus() ) {
+    case SmbException.NT_STATUS_OK:
+        break;
+    case SmbException.NT_STATUS_ACCESS_DENIED:
+    case SmbException.NT_STATUS_WRONG_PASSWORD:
+    case SmbException.NT_STATUS_LOGON_FAILURE:
+    case SmbException.NT_STATUS_ACCOUNT_RESTRICTION:
+    case SmbException.NT_STATUS_INVALID_LOGON_HOURS:
+    case SmbException.NT_STATUS_INVALID_WORKSTATION:
+    case SmbException.NT_STATUS_PASSWORD_EXPIRED:
+    case SmbException.NT_STATUS_ACCOUNT_DISABLED:
+    case SmbException.NT_STATUS_ACCOUNT_LOCKED_OUT:
+        // get new authentication credentials and try again
+}
+
+ +This is cumbersome. Fortunately, jCIFS provides a mechanism to do the equivalent of the above internally and throw an SmbAuthException instead of the more generic SmbException. SmbAuthException extends SmbException but provides no additional functionality other than being a different class to catch: + +
+} catch( SmbAuthException sae ) {
+    // handle authentication related issue here
+} catch( SmbException se ) {
+    // any special SMB related exception handling
+}
+
+ +This is useful by itself but there's an addition facility for handing these exceptions. + +

NtlmAuthenticator and NtlmAuthenticator.setDefault( NtlmAuthenticator )

+ +Like java.net.Authenticator the NtlmAuthenticator class can be extended by an application and registered with the NtlmAuthenticator.setDefault(jcifs.smb.NtlmAuthenticator) method to add sophisticated authentication handing to an application. When an SmbAuthException occurs the NtlmAuthenticator's getNtlmPasswordAuthentication() implementation will be called. The NtlmPasswordAuthentication object returned will be used to resubmit the request. The developer need not worry about retrying the operation. The authenticator will be called repeatedly until null is returned. Only one NtlmAuthenticator may be registered. + +

+ +The SmbShell example illustrates the use of NtlmAuthenticator: + +
+
+public class SmbShell extends NtlmAuthenticator {
+
+    protected NtlmPasswordAuthentication getNtlmPasswordAuthentication() {
+        System.out.println( getRequestingException().getMessage() +
+                    " for " + getRequestingURL() );
+        System.out.print( "username: " );
+        try {
+            int i;  
+            String username = readLine();
+            String domain = null, password;
+
+            if(( i = username.indexOf( '\\' )) != -1 ) {
+                domain = username.substring( 0, i ); 
+                username = username.substring( i + 1 );
+            }
+            System.out.print( "password: " );
+            password = readLine();
+            if( password.length() == 0 ) {
+                return null;
+            }       
+            return new NtlmPasswordAuthentication( domain, username, password );
+        } catch( Exception e ) {
+        }       
+        return null;
+    }
+
+    public SmbShell( String start ) {
+        this.start = start;
+        NtlmAuthenticator.setDefault( this );
+    }
+
+ +When the SmbShell user tries to access a resource for which they do not have adequate permissions the SmbAuthException will be trapped and the above getNtlmPasswordAuthentication method will be called upon to supply alternative credentials. The commandline dialog of this might look like: + +
+$ java -Djcifs.netbios.wins=192.168.1.15 SmbShell smb://myworkgroup/
+myworkgroup/> cd storage0605/c$/
+The user account has expired for smb://storage0605/c$/
+username: mydomain\miallen
+password: fretos
+c$/>
+
+ + +
+ + Last updated Mar 18, 2009
jcifs-1.3.7
+ Copyright © 2004 The JCIFS Project
+validate this page
+ + diff --git a/docs/authhandler.xml b/docs/authhandler.xml new file mode 100644 index 0000000..e98797c --- /dev/null +++ b/docs/authhandler.xml @@ -0,0 +1,125 @@ + + + +JCIFS Exceptions and NtlmAuthenticator + +This document describes how jCIFS communicates server errors to callers and how authentication related exceptions may be handled differently from regular exceptions. How jCIFS can be used to authenticate arbitrary user credentials is not discussed although it is in the FAQ. + +

SmbException

+ +There are hundreds of error codes that may be returned by a CIFS server. It would be unacceptable to have an Exception class for each so the jCIFS client represents all of these using the SmbException class. The NT STATUS code for an SmbException may be retrieved using it's getNtStatus() method. +

+All of the methods of SmbFile that generate network IO can potentially throw an SmbException. Under normal operation it is not necessary to catch and interrogate each exception however this mechanism provides the developer with an opportunity to make an application more sophisticated and robust in the event of an error. Consider the following example: + +

+while( retry-- ) {
+    try {
+        ...
+        d = f.lastModified();
+        ...
+    } catch( SmbException se ) {
+        if( se.getNtStatus() == SmbException.NT_STATUS_DEVICE_NOT_READY ) {
+            // The tape drive is not ready yet, let's wait a little while
+            Thread.sleep( retryPeriod );
+        } else {
+            throw se;
+        }
+    }
+
+ +In this example (some kind of backup utility that accesses a shared tape drive perhaps) the developer knows that accessing this device will return an NT_STATUS_DEVICE_NOT_READY status code if the tape has not finished rewinding. The SmbException is caught and examined for this condition so that the program may sleep for a predefined amount of time while waiting for the drive to become ready. Otherwise exceptions with status codes other than NT_STATUS_DEVICE_NOT_READY are re-thrown. Adding this kind of support to your application usually requires some experimentation to determine what types of error codes will be returned by a server and in general the technique is not portable. + +

+ +The SmbException class has text messages associated with the more common status codes. The SmbExcption for NT_STATUS_DEVICE_NOT_READY will generate the familiar "The device is not ready" message you get when trying to access a CDROM drive without a disk in it. Of course not all of the various error codes have associated text messages and the ones that do are in English at the moment. + +

+ +Note: Eventually there may be a java.util.ResourceBundle to manage common text messages in various languages. + +

SmbAuthException

+ +One rather common not-so-exceptional set of exceptions are the authentication related exceptions. For example, if an ordinary user attempts to read a file which may only be accessed by a user with "Backup Operator" permissions, the server will return a status code of NT_STATUS_ACCESS_DENIED (at least NT with NTFS will). Similarly if the user is restricted to accessing a server during a prescribed time period, the server may return an NT_STATUS_INVALID_LOGON_HOURS status code. To catch these exceptions (perhaps to ask the user for alternative credentials), using only the mechanism described above, a switch block like the following would be necessary: + +
+switch( se.getNtStatus() ) {
+    case SmbException.NT_STATUS_OK:
+        break;
+    case SmbException.NT_STATUS_ACCESS_DENIED:
+    case SmbException.NT_STATUS_WRONG_PASSWORD:
+    case SmbException.NT_STATUS_LOGON_FAILURE:
+    case SmbException.NT_STATUS_ACCOUNT_RESTRICTION:
+    case SmbException.NT_STATUS_INVALID_LOGON_HOURS:
+    case SmbException.NT_STATUS_INVALID_WORKSTATION:
+    case SmbException.NT_STATUS_PASSWORD_EXPIRED:
+    case SmbException.NT_STATUS_ACCOUNT_DISABLED:
+    case SmbException.NT_STATUS_ACCOUNT_LOCKED_OUT:
+        // get new authentication credentials and try again
+}
+
+ +This is cumbersome. Fortunately, jCIFS provides a mechanism to do the equivalent of the above internally and throw an SmbAuthException instead of the more generic SmbException. SmbAuthException extends SmbException but provides no additional functionality other than being a different class to catch: + +
+} catch( SmbAuthException sae ) {
+    // handle authentication related issue here
+} catch( SmbException se ) {
+    // any special SMB related exception handling
+}
+
+ +This is useful by itself but there's an addition facility for handing these exceptions. + +

NtlmAuthenticator and NtlmAuthenticator.setDefault( NtlmAuthenticator )

+ +Like java.net.Authenticator the NtlmAuthenticator class can be extended by an application and registered with the NtlmAuthenticator.setDefault(jcifs.smb.NtlmAuthenticator) method to add sophisticated authentication handing to an application. When an SmbAuthException occurs the NtlmAuthenticator's getNtlmPasswordAuthentication() implementation will be called. The NtlmPasswordAuthentication object returned will be used to resubmit the request. The developer need not worry about retrying the operation. The authenticator will be called repeatedly until null is returned. Only one NtlmAuthenticator may be registered. + +

+ +The SmbShell example illustrates the use of NtlmAuthenticator: + +

+public class SmbShell extends NtlmAuthenticator {
+
+    protected NtlmPasswordAuthentication getNtlmPasswordAuthentication() {
+        System.out.println( getRequestingException().getMessage() +
+                    " for " + getRequestingURL() );
+        System.out.print( "username: " );
+        try {
+            int i;  
+            String username = readLine();
+            String domain = null, password;
+
+            if(( i = username.indexOf( '\\' )) != -1 ) {
+                domain = username.substring( 0, i ); 
+                username = username.substring( i + 1 );
+            }
+            System.out.print( "password: " );
+            password = readLine();
+            if( password.length() == 0 ) {
+                return null;
+            }       
+            return new NtlmPasswordAuthentication( domain, username, password );
+        } catch( Exception e ) {
+        }       
+        return null;
+    }
+
+    public SmbShell( String start ) {
+        this.start = start;
+        NtlmAuthenticator.setDefault( this );
+    }
+
+ +When the SmbShell user tries to access a resource for which they do not have adequate permissions the SmbAuthException will be trapped and the above getNtlmPasswordAuthentication method will be called upon to supply alternative credentials. The commandline dialog of this might look like: + +
+$ java -Djcifs.netbios.wins=192.168.1.15 SmbShell smb://myworkgroup/
+myworkgroup/> cd storage0605/c$/
+The user account has expired for smb://storage0605/c$/
+username: mydomain\miallen
+password: fretos
+c$/>
+
+ +
diff --git a/docs/batching.html b/docs/batching.html new file mode 100644 index 0000000..6dce120 --- /dev/null +++ b/docs/batching.html @@ -0,0 +1,92 @@ +Batching +
+ +

Batching

+ +The CIFS protocol provides a mechanism for issuing several commands in a single message. This performance enhancement is called "batching" or "chaining". For example an SMB_COM_TREE_CONNECT_ANDX is often batched "inside" an SMB_COM_SESSION_SETUP_ANDX. Furthermore, an SMB_COM_QUERY_INFORMATION might be batched in the SMB_COM_TREE_CONNECT_ANDX resulting in three commands being issued to the server in one message. There are of course many more permutations that can occur. + +

Tuning Batched Requests

+ +Do not change batch level properties. They are considered advanced properties and should not be changed unless instructed to do so or if you really know what your doing. Setting a batch level property may result in commands failing on one machine and not on another in mysterious ways. + +

This library can optimally batch any request with any other although it is prevented from doing so in accordance with the CIFS specification. The CIFS specification does not, however, specify how many commands may be batched together in a given message. Below is a list of jcifs property identifiers that may be used to tune the "batch level" a command may assume relative to it's precedent command. For example the SessionSetupAndX may be followed by a TreeConnectAndX (that is to say the TreeConnectAndX is batched in the SessionSetupAndX) as indicated by it's subcategorized placement under SessionSetupAndX in the below list. + +

+
+SessionSetupAndX
+    TreeConnectAndX
+
+TreeConnectAndX
+    CheckDirectory
+    CreateDirectory
+    Delete
+    DeleteDirectory
+    OpenAndX
+    Rename
+    Transaction
+    QueryInformation
+
+OpenAndX
+    ReadAndX
+
+NTCreateAndX
+    ReadAndX
+
+ReadAndX
+    Close
+
+WriteAndX
+    ReadAndX
+    Close
+
+
+ +By default all commands are permitted to batch with their parent only one level deep. So at most only two commands may be issued in one message. To instruct jcifs to restrict a command from being batched at all or enable a command to be at most the second, third, or the Nth place command one might set a property like: + +
+jcifs.smb.client.TreeConnectAndX.QueryInformation = 2
+
+ +Batch level properties begin with jcifs.smb.client followed by one of the parent commands in the list above (AndX commands) and the command to be batched (must be listed under the the parent). The value must be an integer indicating the "batch level". The above example would instruct jcifs that the QueryInformation command may be batched with the TreeConnectAndX command only if it is the second command or less in a series of batched commands. So for example a SessionSetupAndX followed by a TreeConnectAndX followed by a QueryInformation may batch in the same message because by default the TreeConnectAndX may be the first in a series and, according to the example property above, the QueryInformation may be the second of a series, which in this case it is. If however this property read: + +
+jcifs.smb.client.TreeConnectAndX.QueryInformation = 0
+
+ +the above scenario would result in the SessionSetupAndX and TreeConnectAndX commands being issued to the server first followed by the QueryInformation by itself in a separate message. IOW the zero would specifies that QueryInformation may not be batched with TreeConnectAndX at all. + +

Potential Problems

+ +Unfortunately it appears as though most(if not all) servers allow for batching on a message by message basis. Meaning it is not uniformly supported. For example NT will allow the QueryInformation to appear as the second command (double batched) of a SessionSetupAndX and TreeConnectAndX whereas Samba will only allow the single batch. It is generally assumed that all messages indicated in the CIFS specification as batchable may be single batched. + +

Why Should Batching Behavior Be Changed?

+ +Again, in all likelyhood you would not want to change these properties. However there are at least three reasons why one might want to change batching behavior. One is if a special message is manually constructed to perform a specific function and batch all messages together must be enabled. For example SessionSetupAndX, TreeConnectAndX, OpenAndX, ReadAndX, and Close might all be batched together so that a small file could be read in one message. Under certain conditions this might prove to be a huge performace benifit(if you read 100 files on 100 different servers quickly for example). However it is highly unlikely that any server would support batching to this degree. + +

Contrarily, it might be discovered that a particular server does not support batching in one form or another in which case it can be turned off. This can be occomplished by specifying a batch level of 0 for the errant command(s) or more easily by simply setting the jcifs.smb.client.useBatching property to false. + +

Another reason might be that a CIFS developer is tesing/developing a server's batching functionality. + +

+
+jcifs.smb.client.SessionSetupAndX.TreeConnectAndX = 1
+jcifs.smb.client.TreeConnectAndX.CheckDirectory = 1
+jcifs.smb.client.TreeConnectAndX.CreateDirectory = 1
+jcifs.smb.client.TreeConnectAndX.Delete = 1
+jcifs.smb.client.TreeConnectAndX.DeleteDirectory = 1
+jcifs.smb.client.TreeConnectAndX.Delete = 1
+jcifs.smb.client.TreeConnectAndX.OpenAndX = 1
+jcifs.smb.client.TreeConnectAndX.OpenAndX = 1
+jcifs.smb.client.TreeConnectAndX.Rename = 1
+jcifs.smb.client.TreeConnectAndX.Transaction = 1
+jcifs.smb.client.TreeConnectAndX.QueryInformation = 1
+jcifs.smb.client.OpenAndX.ReadAndX = 1
+jcifs.smb.client.NTCreateAndX.ReadAndX = 1
+jcifs.smb.client.ReadAndX.Close = 1
+jcifs.smb.client.WriteAndX.ReadAndX = 1
+jcifs.smb.client.WriteAndX.Close = 1
+
+
+ +
+ diff --git a/docs/capture.html b/docs/capture.html new file mode 100644 index 0000000..35f38ce --- /dev/null +++ b/docs/capture.html @@ -0,0 +1,168 @@ + + + + + + + + + +

Obtaining a Network Packet Capture

+ +A packet capture is a recording of network traffic. These can be extremely useful when trying to decipher problems with network capable softare. +If for example, you are having a problem with the jCIFS client that you do not understand you might send a message to the jCIFS mailing list with an explaination of the problem, which version of jCIFS you're using, etc. +Depending on the problem it is desireable to also have a packet capture of the errant traffic and, for maximum results, a packet capture of the analygous operation succeeding (preferrably with a Windows 2000 client which is what jCIFS tries to emulate as closely as possible). Do not send packet captures to public mailing lists if you are not certain it does not contain personal information such as password hashes. If the captures are required a developers will instruct you to send them directly. + +

How to Obtain a Packet Capture

+ +To take a packet capture of network traffic it is necessary to run special software on a machine that is capable of receiving the traffic of interest. There are many programs that can do this. Three popular ones are: + +
    + +
  • +Tcpdump is a command line utility for UNIX (there's also a windump for Windows). Tcpdump is virtually guaranteed to be distributed with your favorite Linux distribution. Otherwise you will need to find a package for your machine/architecture.
  • + +
  • +Ethereal is a GUI based application that will capture packets as well as display the individial fields within packets. Ethereal is also probably distributed with your favorite Linux distobution. Otherwise it can be obtained at http://www.ethereal.com. It runs on UNIX as well and even Windows with an additional packet capture driver.
  • + +
  • +NetMon is a Windows application that will capture packets as well as display some information within packets (not as much as Ethereal). NetMon is usually bundled with other networking oriented packages such as SMS.
  • + +
+ +The packet capture program will need to run on the server (e.g. CIFS server), client (e.g. machine from which you are running the jCIFS client), or a machine connected to the same network as the server or client without a switch in between. For example if you insert a simple hub between the client and server a workstation or laptop plugged into the hub should also be able to capture traffic of any client connected to the hub. + +

Tcpdump

+Tcpdump is a commandline packet capture program for Linux and UNIX. Here is some sample output: + +
+[root@miallen3 root]# tcpdump 'port 137 || 138 || 139 || 445'
+tcpdump: listening on eth0
+00:35:54.713969 miallen3.foo.net.54090 > wins.netbios-ns: NBT UDP PACKET(137): QUERY; REQUEST; UNICAST (DF)
+00:35:55.110033 wins.netbios-ns > miallen3.foo.net.54090: NBT UDP PACKET(137): QUERY; POSITIVE; RESPONSE; UNICAST
+00:35:55.237285 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: S 781540350:781540350(0) win 5840 <mss 1460,sackOK,timestamp 294697799 0,nop,wscale 0> (DF)
+00:35:55.237426 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: S 30250517:30250517(0) ack 781540351 win 64512 <mss 1460> (DF)
+00:35:55.237457 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 1 win 5840 (DF)
+00:35:55.247119 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 1:73(72) ack 1 win 5840NBT Packet (DF)
+00:35:55.247296 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 1:5(4) ack 73 win 64440NBT Packet (DF)
+00:35:55.247340 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 5 win 5840 (DF)
+00:35:55.257196 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 73:124(51) ack 5 win 5840NBT Packet (DF)
+00:35:55.257374 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 5:102(97) ack 124 win 64389NBT Packet (DF)
+00:35:55.293769 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 102 win 5840 (DF)
+00:35:55.323760 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 124:336(212) ack 102 win 5840NBT Packet (DF)
+00:35:55.386059 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 102:254(152) ack 336 win 64177NBT Packet (DF)
+00:35:55.386090 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 254 win 5840 (DF)
+00:35:55.395819 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 336:462(126) ack 254 win 5840NBT Packet (DF)
+00:35:55.399767 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 254:361(107) ack 462 win 64051NBT Packet (DF)
+00:35:55.403169 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 462:588(126) ack 361 win 5840NBT Packet (DF)
+00:35:55.403585 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 361:468(107) ack 588 win 63925NBT Packet (DF)
+00:35:55.427905 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 588:704(116) ack 468 win 5840NBT Packet (DF)
+00:35:55.428252 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 468:532(64) ack 704 win 63809NBT Packet (DF)
+00:35:55.432571 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 704:749(45) ack 532 win 5840NBT Packet (DF)
+00:35:55.432825 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 532:571(39) ack 749 win 63764NBT Packet (DF)
+00:35:55.448894 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: F 749:749(0) ack 571 win 5840 (DF)
+00:35:55.449059 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: F 571:571(0) ack 750 win 63764 (DF)
+00:35:55.449110 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 572 win 5840 (DF)
+
+25 packets received by filter
+0 packets dropped by kernel
+
+ +The above is not a full packet capture. It just prints summary output to the terminal window. Each line represents one network packet. The columns can differ depending on the protocol of the packet but the first three columns are the time the packet was received, the source host and port, and the destination host and port. Sometimes hostnames are used instead of IP addresses and ports can be substituted with the service name from /etc/services (e.g. 'netbios-ssn' over which CIFS/SMB traffic is transferred is port 139). + +

+ +To obtain a full packet capture with tcpdump you need to use '-s 0' to prevent the payload from being stipped and direct the ouput to a file like the following: + +
+[root@miallen3 root]# tcpdump -s 0 -w mycapture.pcap 'port 137 || 138 || 139 || 445'
+tcpdump: listening on eth0
+
+38 packets received by filter
+0 packets dropped by kernel
+
+ +Notice you must be root to run any packet capture software. This is because the networking card needs to be switched into "promiscuous mode". Sometimes a computer will beep when this happends to indicate to adminstrative personnel that someone is actively capturing traffic. The expression at the end of the commandline above instructs tcpdump to listen for packets on ports 137, 138, 139, and 445. These are the ports of interest for the CIFS/SMB protocol. If no expression is provided all traffic will be captured. + +

Ethereal

+ +Ethereal is a packet capture program but it also has a very nice user interface for examining the contents of packets. For example, the jCIFS client was developed almost entirely from viewing Ethereal packet captures. Ethereal will also understand NetMon and tcpdump packet captures. + +

+ +To capture packets using Ethereal start it as root by just typing 'ethereal'. This will launch the UI. Select Capture > Start and change the Interface to 'any'. Enter a filter if necessary. For example, to capture jCIFS traffic enter a filter of 'port 137 || 138 || 139 || 445' (and maybe add '|| port 8080' for NTLM HTTP traffic or whatever port your Servlet container is servicing clients on). Click on Ok to start capturing packets. Now perform the operation you wish to capture and hit stop. See if the traffic of interest has been captured and use File > Save As to save it as libpcap format. I recommend using a file extension of '.pcap' for Ethereal captures to distinquish between libpcap captures and NetMon captures which use filename extensions of '.cap'. + +

Microsoft NetMon

+ +If you do not have root access to Linux or UNIX machine with packet capture software on the network of interest try to get a copy of NetMon for Windows. NetMon is also a GUI. It isn't as nice as Ethereal but it will permit you get capture packets just the same. NetMon is usually packaged as an add-on for other software like SMS. + +
+ + Last updated Mar 18, 2009
jcifs-1.3.7
+ Copyright © 2004 The JCIFS Project
+validate this page
+ + diff --git a/docs/capture.xml b/docs/capture.xml new file mode 100644 index 0000000..d68f7b4 --- /dev/null +++ b/docs/capture.xml @@ -0,0 +1,86 @@ + + + +Obtaining a Network Packet Capture + +A packet capture is a recording of network traffic. These can be extremely useful when trying to decipher problems with network capable softare. +If for example, you are having a problem with the jCIFS client that you do not understand you might send a message to the jCIFS mailing list with an explaination of the problem, which version of jCIFS you're using, etc. +Depending on the problem it is desireable to also have a packet capture of the errant traffic and, for maximum results, a packet capture of the analygous operation succeeding (preferrably with a Windows 2000 client which is what jCIFS tries to emulate as closely as possible). Do not send packet captures to public mailing lists if you are not certain it does not contain personal information such as password hashes. If the captures are required a developers will instruct you to send them directly. + +

How to Obtain a Packet Capture

+ +To take a packet capture of network traffic it is necessary to run special software on a machine that is capable of receiving the traffic of interest. There are many programs that can do this. Three popular ones are: + +
    +
  • Tcpdump is a command line utility for UNIX (there's also a windump for Windows). Tcpdump is virtually guaranteed to be distributed with your favorite Linux distribution. Otherwise you will need to find a package for your machine/architecture.
  • +
  • Ethereal is a GUI based application that will capture packets as well as display the individial fields within packets. Ethereal is also probably distributed with your favorite Linux distobution. Otherwise it can be obtained at http://www.ethereal.com. It runs on UNIX as well and even Windows with an additional packet capture driver.
  • +
  • NetMon is a Windows application that will capture packets as well as display some information within packets (not as much as Ethereal). NetMon is usually bundled with other networking oriented packages such as SMS.
  • +
+ +The packet capture program will need to run on the server (e.g. CIFS server), client (e.g. machine from which you are running the jCIFS client), or a machine connected to the same network as the server or client without a switch in between. For example if you insert a simple hub between the client and server a workstation or laptop plugged into the hub should also be able to capture traffic of any client connected to the hub. + +

Tcpdump

+Tcpdump is a commandline packet capture program for Linux and UNIX. Here is some sample output: + +
+[root@miallen3 root]# tcpdump 'port 137 || 138 || 139 || 445'
+tcpdump: listening on eth0
+00:35:54.713969 miallen3.foo.net.54090 > wins.netbios-ns: NBT UDP PACKET(137): QUERY; REQUEST; UNICAST (DF)
+00:35:55.110033 wins.netbios-ns > miallen3.foo.net.54090: NBT UDP PACKET(137): QUERY; POSITIVE; RESPONSE; UNICAST
+00:35:55.237285 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: S 781540350:781540350(0) win 5840 <mss 1460,sackOK,timestamp 294697799 0,nop,wscale 0> (DF)
+00:35:55.237426 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: S 30250517:30250517(0) ack 781540351 win 64512 <mss 1460> (DF)
+00:35:55.237457 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 1 win 5840 (DF)
+00:35:55.247119 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 1:73(72) ack 1 win 5840NBT Packet (DF)
+00:35:55.247296 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 1:5(4) ack 73 win 64440NBT Packet (DF)
+00:35:55.247340 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 5 win 5840 (DF)
+00:35:55.257196 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 73:124(51) ack 5 win 5840NBT Packet (DF)
+00:35:55.257374 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 5:102(97) ack 124 win 64389NBT Packet (DF)
+00:35:55.293769 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 102 win 5840 (DF)
+00:35:55.323760 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 124:336(212) ack 102 win 5840NBT Packet (DF)
+00:35:55.386059 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 102:254(152) ack 336 win 64177NBT Packet (DF)
+00:35:55.386090 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 254 win 5840 (DF)
+00:35:55.395819 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 336:462(126) ack 254 win 5840NBT Packet (DF)
+00:35:55.399767 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 254:361(107) ack 462 win 64051NBT Packet (DF)
+00:35:55.403169 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 462:588(126) ack 361 win 5840NBT Packet (DF)
+00:35:55.403585 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 361:468(107) ack 588 win 63925NBT Packet (DF)
+00:35:55.427905 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 588:704(116) ack 468 win 5840NBT Packet (DF)
+00:35:55.428252 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 468:532(64) ack 704 win 63809NBT Packet (DF)
+00:35:55.432571 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: P 704:749(45) ack 532 win 5840NBT Packet (DF)
+00:35:55.432825 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: P 532:571(39) ack 749 win 63764NBT Packet (DF)
+00:35:55.448894 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: F 749:749(0) ack 571 win 5840 (DF)
+00:35:55.449059 MIALLEN2.foo.net.netbios-ssn > miallen3.foo.net.46250: F 571:571(0) ack 750 win 63764 (DF)
+00:35:55.449110 miallen3.foo.net.46250 > MIALLEN2.foo.net.netbios-ssn: . ack 572 win 5840 (DF)
+
+25 packets received by filter
+0 packets dropped by kernel
+
+ +The above is not a full packet capture. It just prints summary output to the terminal window. Each line represents one network packet. The columns can differ depending on the protocol of the packet but the first three columns are the time the packet was received, the source host and port, and the destination host and port. Sometimes hostnames are used instead of IP addresses and ports can be substituted with the service name from /etc/services (e.g. 'netbios-ssn' over which CIFS/SMB traffic is transferred is port 139). + +

+ +To obtain a full packet capture with tcpdump you need to use '-s 0' to prevent the payload from being stipped and direct the ouput to a file like the following: + +

+[root@miallen3 root]# tcpdump -s 0 -w mycapture.pcap 'port 137 || 138 || 139 || 445'
+tcpdump: listening on eth0
+
+38 packets received by filter
+0 packets dropped by kernel
+
+ +Notice you must be root to run any packet capture software. This is because the networking card needs to be switched into "promiscuous mode". Sometimes a computer will beep when this happends to indicate to adminstrative personnel that someone is actively capturing traffic. The expression at the end of the commandline above instructs tcpdump to listen for packets on ports 137, 138, 139, and 445. These are the ports of interest for the CIFS/SMB protocol. If no expression is provided all traffic will be captured. + +

Ethereal

+ +Ethereal is a packet capture program but it also has a very nice user interface for examining the contents of packets. For example, the jCIFS client was developed almost entirely from viewing Ethereal packet captures. Ethereal will also understand NetMon and tcpdump packet captures. + +

+ +To capture packets using Ethereal start it as root by just typing 'ethereal'. This will launch the UI. Select Capture > Start and change the Interface to 'any'. Enter a filter if necessary. For example, to capture jCIFS traffic enter a filter of 'port 137 || 138 || 139 || 445' (and maybe add '|| port 8080' for NTLM HTTP traffic or whatever port your Servlet container is servicing clients on). Click on Ok to start capturing packets. Now perform the operation you wish to capture and hit stop. See if the traffic of interest has been captured and use File > Save As to save it as libpcap format. I recommend using a file extension of '.pcap' for Ethereal captures to distinquish between libpcap captures and NetMon captures which use filename extensions of '.cap'. + +

Microsoft NetMon

+ +If you do not have root access to Linux or UNIX machine with packet capture software on the network of interest try to get a copy of NetMon for Windows. NetMon is also a GUI. It isn't as nice as Ethereal but it will permit you get capture packets just the same. NetMon is usually packaged as an add-on for other software like SMS. + +
diff --git a/docs/faq.html b/docs/faq.html new file mode 100644 index 0000000..8870010 --- /dev/null +++ b/docs/faq.html @@ -0,0 +1,342 @@ + + + + + + + + + +

JCIFS Frequently Asked Questions

+ + +
    + +
  1. +How do I do NTLM HTTP authentication (a.k.a Single Sign On) for my website? +
  2. + +
  3. +Does jCIFS support NTLMv2? +
  4. + +
  5. +Why is java.net.URL throwing unknown protocol: smb Exceptions? +
  6. + +
  7. +I'm getting these UnknownHostExceptions right from the start. What am I doing wrong? +
  8. + +
  9. +Why do I get these "Network is unreachable" IOExceptions? +
  10. + +
  11. +How can I authenticate arbitrary user credentials from an application or web clients against Active Directory? +
  12. + +
+ + + +Q: How do I do NTLM HTTP authentication (a.k.a Single Sign On) for my website? +

+ +A: See "Jespa": +
+ +http://www.ioplex.com/jespa.html + +
+Jespa is a complete NTLM implementation in 100% Java that properly implements both the server and client side of NTLMv2, NTLMv1, NTLM2 Session Security and Key Exchange. +Of particular interest to users of the old JCIFS SSO Filter, Jespa can properly authenticate NTLMv2 clients just like a Windows server does (using the NetrLogonSamLogon DCERPC call over NETLOGON w/ Secure Channel) and it includes an HTTP SSO Servlet Filter. +

+Note: Jespa uses JCIFS for DCERPC transport and some basic client side NTLM calculations. Jespa is not Open Source (although it is free for up to 25 users). Please contact IOPLEX Software support if you have any questions regarding Jespa. +

+Note: The old SSO Filter that used to be included with JCIFS used a "man in the middle" technique that cannot support NTLMv2 and has therefore been removed from the JCIFS package. See the following post for details: +

+ +
+ +http://lists.samba.org/archive/jcifs/2008-October/008227.html + +
+ +

+ + + + + +Q: Does jCIFS support NTLMv2? +

+ +A: Yes. As of 1.3.0, JCIFS fully supports NTLMv2 and uses it by default. +

+Note: The NTLM HTTP SSO Filter that used to be included with JCIFS cannot support NTLMv2. See the above question for details. +

+ + + + + +Q: Why is java.net.URL throwing unknown protocol: smb Exceptions? +
+Exception in thread "main" java.net.MalformedURLException: unknown protocol: smb
+        at java.net.URL.<init>(URL.java:480)
+        at java.net.URL.<init>(URL.java:376)
+        at java.net.URL.<init>(URL.java:330)
+        at jcifs.smb.SmbFile.<init>(SmbFile.java:355)
+        ...
+
+ +A: The SMB URL protocol handler is not being successfully installed. In short, the jCIFS jar must be loaded by the System class loader. The problem is reported frequently with servlet containers that load the jCIFS jar using a more restricted class loader (i.e. placing the jar in WEB-INF/lib is not adequate). In this case the solution is to add the jar to the servlet container's CLASSPATH (for Resin this is simply a matter of placing it in the top level lib directory). +

+More specifically, the SMB URL protocol handler (jcifs.smb.Handler) is used by the java.net.URL class to provide the Java "smb://" URL implementation. There are two possible reasons why this handler is not being recognized. +
    + +
  1. +The current security policy is preventing jCIFS from setting the java.protocol.handler.pkgs system property which is required to install the SMB URL protocol handler. For example, some servlet containers install a security manager or restrictive policy file. In this case, add the jCIFS jar file to the container's CLASSPATH because servlet containers usually associate a policy file with the class files of web applications. Otherwise, the specific (minimum) grant required by jCIFS to successfully install the SMB URL protocol handler is: +
    +permission java.util.PropertyPermission "java.protocol.handler.pkgs", "read, write";
    +
    +If jCIFS is not permitted to write this system property, the SecurityException throw will be caught and a message will be printed to System.err. Alternatively the property can also be set using a VM command line parameter: +
    +java -Djava.protocol.handler.pkgs=jcifs ...
    +
    +This should permit the URL protocol handler to be installed regardless of what security policy is installed (however this isn't recommended as it will override other protocol handlers). +
  2. +
  3. +The jCIFS jar file is not in a suitable location. Even if the java.protocol.handler.pkgs property is set successfully, the java.net.URL class must then access the jcifs.smb.Handler class. But if the jCIFS classes are loaded by a different class loader this handler will not be found and again, you will get the "unknown protocol: smb" exception. It is very common for servlet containers to load classes from a class loader other than the System class loader. Like the first scenario, the solution is to add the jCIFS jar file to the container's CLASSPATH and not the WEB-INF/lib directory of the web app. +
  4. + +
+ + + + + +Q: I'm getting these UnknownHostExceptions right from the start. What am I doing wrong? +
+$ java List smb://server/share/
+Exception in thread "main" java.net.UnknownHostException: SERVER<20>
+        at jcifs.netbios.NbtAddress.doNameQuery(NbtAddress.java, Compiled Code)
+        at jcifs.netbios.NbtAddress.getByName(NbtAddress.java, Compiled Code)
+        at jcifs.smb.SmbFile.<init>(SmbFile.java, Compiled Code)
+        at jcifs.smb.SmbFile.<init>(SmbFile.java, Compiled Code)
+        at List.main(List.java, Compiled Code)
+
+ +

+ +A: In a nutshell, this is what happens when jCIFS cannot even find the target host. +

+For jCIFS to access another computer's files and services the target must be running a CIFS server over a NetBIOS LAN. This is exactly the case with 90% of MS Windows networks as CIFS over NetBIOS is MS's native networking setup. In this environment jCIFS should work flawlessly. However the above UnknownHostException is occurring because the name of the target computer cannot be resolved. There could be many reasons why this is happening. + +

Breakdown of Possible Name Resolution Problems:

+ + +
    + +
  • +The name really doesn't exist. The computer name is misspelled or the machine is off. Doah! + +
  • +
  • +The target is on a different subnet and the name service properties are not set correctly. Larger computer networks are divided up into "subnets". In this case a WINS server is required to resolve hostnames (although fully qualified DNS names will work just as well). The jcifs.netbios.wins property must be set to the IP address of the WINS server for your network. +

    +See the Setting Client Properties page for information on how to set jCIFS properties. Also see the Setting Name Resolution Properties page for more detail about resolver properties and what they do. You might also ask your network administrator about what NetBIOS name services are available or check the Network Settings of a nearby MS Windows host for this information. + +
  • +
  • +The target computer is not running a CIFS server. Not all operating systems have CIFS servers running. Generally Windows NT, Windows 95/98/ME/2000/XP, Samba on UNIX, and possibly OS/2 should work fine (although you can run jCIFS from any computer with an adequate version of Java). The best way to confirm that the target is in fact running a CIFS server is to try to "share" a folder on the target machine and access files on it from another machine (see Diagnostics below). Otherwise you may need to configure it to run a CIFS server ( e.g. Samba on Linux) or get third party software (e.g. Thursby Software's Dave for MacOS). Note, Windows 95/98/ME do not have the CIFS server running by default -- you must "Allow others access to my files" under Control Panel > Network Settings first. + +
  • +
  • +You are using the NetBIOS "scope id". This is rarely encountered but you may need to set the jcifs.netbios.scope property. Ask your network administrator if a NetBIOS scope id is being used and look at the Network Settings of nearby machines. It will just be a string like 'CHEM_BLDNG' or 'scope.com' or similar. See the Setting Name Resolution Properties page for more information about scope and other properties that control hostname resolution. + +
  • +
  • +Your hostname is resolving to 127.0.0.1. It is not uncommon on Linux for an /etc/hosts file to map the hostname to 127.0.0.1 such as: +
    +127.0.0.1      nano   localhost.localdomain    localhost
    +
    +Taking the host name (e.g. nano) out of the localhost line should solved the problem. + +
  • +
  • +JCIFS is not reading the properties file. If you are using the -Djcifs.properties=<filename.prp> command line option, make sure you spell it correctly or the properties file will silently be ignored, including any important name service properties within it. +
  • + +
+ +In general, if jCIFS is producing unwarranted UnknownHostExceptions, you will need to find out a little more about your network. Be sure to read the Setting Client Properties section from the API Documentation and pay close attention to the jcifs.netbios.wins property. Connecting to Windows machines on the local subnet should work even without setting the WINS property. To connect to a machine on another subnet you can use the IP address of the host (eg. smb://192.168.1.15/someshare/) or set the jcifs.netbios.wins property and use NetBIOS server names. Below are some diagnostics that might help. + +

Diagnosis:

+Personally I much prefer to take a packet capture when trying to diagnose networking issues. See Obtaining a Network Packet Capture for instructions on how to do that. +

+Otherwise, first check to see if your local hostname reverse-resolves properly. On UNIX you should look at your /etc/hosts file to make sure it's not mapped to 127.0.0.1. Otherwise just try pinging yourself. The below shows a problem. It should really be resolving to the real IP. +
+[miallen@nano jcifs]$ ping nano
+PING nano (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.    // 127.0.0.1 INCORRECT
+64 bytes from nano (127.0.0.1): icmp_seq=0 ttl=255 time=0.1 ms
+...
+[miallen@bogus jcifs]$ ping bogus
+PING bogus.research.ml.com (172.32.29.134) from 172.32.29.134 : 56(84) bytes of data. // Real IP is CORRECT
+64 bytes from bogus.research.ml.com (172.32.29.134): icmp_seq=1 ttl=255 time=0.090 ms
+
+ +There are many ways to test the machines on your network for the necessary NetBIOS name services. If you have a Windows machine available you can use nbtstat and ipconfig. On Linux and UNIX you can use ifconfig and nmblookup (nmblookup is from the Samba package). More specifically try: +
+C:\> ipconfig
+or
+C:\> ipconfig /all
+to confirm your IP address(e.g. 192.168.1.15) and then do:
+C:\> nbtstat -A 192.168.1.15
+
+You should get the netbios hostname of the machine as well as some other useful information. You can now do this on other hosts as well provided you know their IP addresses. If this is working and the necessary properties are set correctly jCIFS should work flawlessly. +

+The Samba suite has a similar tool that you can use on Linux and UNIX. Again, first verify your IP address with: +
+$ /sbin/ifconfig
+$ nmblookup -A 192.168.1.15
+
+If any of the above fails you need to look closer at your network settings or have a discussion with your network administrator. But if you determine that the NetBIOS service is in fact listening on the targets of interest you can use the net command on Windows, smbclient on Linux/UNIX, or jCIFS to test connecting to services: +
+C:\> net use * \\servername\share
+
+or on UNIX with +
+$ smbclient -L //servername
+$ smbclient //servername/share
+$ smbclient //servername/share -W research
+                            // -W required for domain auth
+
+If the above works the below List example (in the examples directory) should work as well. Try it with -Djcifs.util.loglevel=10 to see detailed log messages. +
+$ java -Djcifs.util.loglevel=10 List smb://server/share/
+
+ + + + + +Q: Why do I get these "Network is unreachable" IOExceptions? +
+java.io.IOException: Network is unreachable
+at java.net.PlainDatagramSocketImpl.send(Native Method)
+at java.net.DatagramSocket.send(DatagramSocket.java, Compiled Code)
+at jcifs.netbios.NameServiceClient.send(NameServiceClient.java, Compiled Code)
+...
+
+ + +A: +Most likely you need to set the broadcast address that jCIFS should use to broadcast name query requests. The Java Language does not provide a way to extract this information from a host so we simply try to use '255.255.255.255'. This will work with most network configurations, however this will fail under certain conditions producing the above exception. +

+To set the broadcast address, use the jcifs.netbios.baddr property such as adding jcifs.netbios.baddr=192.168.1.255 or similar to your properties or use -Djcifs.netbios.baddr=192.168.1.255 on the commandline. You can determine your proper broadcast address by running the ipconfig command on Windows or /sbin/ifconfig on Unix (Linux at least). See the Setting JCIFS Properties page for details. +
+C:\> ipconfig
+C:\> ipconfig /all
+or on Linux:
+$ /sbin/ifconfig
+
+Another cause of this is if your host does not have a suitable network interface over which to communicate (e.g. laptops with certain power management facilities can switch the NIC to powersave mode if theres nothing plugged into it). +

+ + + + + +Q: How can I authenticate arbitrary user credentials from an application or web clients against Active Directory? +

+ +A: There are two ways to do this. One is to use the jcifs.smb.Session.logon() method to perform an SMB_COM_SESSION_SETUP_ANDX like: +
+UniAddress mydomaincontroller = UniAddress.getByName( "192.168.1.15" );
+NtlmPasswordAuthentication mycreds = new NtlmPasswordAuthentication( "ntdom", "user", "pass" );
+try {
+    SmbSession.logon( mydomaincontoller, mycreds );
+    // SUCCESS
+    return true;
+} catch( SmbAuthException sae ) {
+    // AUTHENTICATION FAILURE
+    return false;
+} catch( SmbException se ) {
+    // NETWORK PROBLEMS?
+    se.printStackTrace();
+}
+
+ +However, just like using an LDAP "bind" to validate credentials, the above method is a mild abuse of the protocol and can cause issues (e.g. with personal workstation AD security policy). The only way to properly validate NTLM credentials is with a NetrLogonSamLogon DCERPC call with the NETLOGON service. The only 100% Java solution that does that is Jespa. +
+ + Last updated Mar 18, 2009
jcifs-1.3.7
+ Copyright © 2004 The JCIFS Project
+validate this page
+ + diff --git a/docs/faq.xml b/docs/faq.xml new file mode 100644 index 0000000..748901b --- /dev/null +++ b/docs/faq.xml @@ -0,0 +1,211 @@ + + + +JCIFS Frequently Asked Questions + +
    +
  1. How do I do NTLM HTTP authentication (a.k.a Single Sign On) for my website?
  2. +
  3. Does jCIFS support NTLMv2?
  4. +
  5. Why is java.net.URL throwing unknown protocol: smb Exceptions?
  6. +
  7. I'm getting these UnknownHostExceptions right from the start. What am I doing wrong?
  8. +
  9. Why do I get these "Network is unreachable" IOExceptions?
  10. +
  11. How can I authenticate arbitrary user credentials from an application or web clients against Active Directory?
  12. +
+ + +Q: How do I do NTLM HTTP authentication (a.k.a Single Sign On) for my website? +

+A: See "Jespa": +

+http://www.ioplex.com/jespa.html +
+Jespa is a complete NTLM implementation in 100% Java that properly implements both the server and client side of NTLMv2, NTLMv1, NTLM2 Session Security and Key Exchange. +Of particular interest to users of the old JCIFS SSO Filter, Jespa can properly authenticate NTLMv2 clients just like a Windows server does (using the NetrLogonSamLogon DCERPC call over NETLOGON w/ Secure Channel) and it includes an HTTP SSO Servlet Filter. +

+Note: Jespa uses JCIFS for DCERPC transport and some basic client side NTLM calculations. Jespa is not Open Source (although it is free for up to 25 users). Please contact IOPLEX Software support if you have any questions regarding Jespa. +

+Note: The old SSO Filter that used to be included with JCIFS used a "man in the middle" technique that cannot support NTLMv2 and has therefore been removed from the JCIFS package. See the following post for details: +

+

+http://lists.samba.org/archive/jcifs/2008-October/008227.html +
+

+ + + + +Q: Does jCIFS support NTLMv2? +

+A: Yes. As of 1.3.0, JCIFS fully supports NTLMv2 and uses it by default. +

+Note: The NTLM HTTP SSO Filter that used to be included with JCIFS cannot support NTLMv2. See the above question for details. +

+ + + + +Q: Why is java.net.URL throwing unknown protocol: smb Exceptions? +

+Exception in thread "main" java.net.MalformedURLException: unknown protocol: smb
+        at java.net.URL.<init>(URL.java:480)
+        at java.net.URL.<init>(URL.java:376)
+        at java.net.URL.<init>(URL.java:330)
+        at jcifs.smb.SmbFile.<init>(SmbFile.java:355)
+        ...
+
+A: The SMB URL protocol handler is not being successfully installed. In short, the jCIFS jar must be loaded by the System class loader. The problem is reported frequently with servlet containers that load the jCIFS jar using a more restricted class loader (i.e. placing the jar in WEB-INF/lib is not adequate). In this case the solution is to add the jar to the servlet container's CLASSPATH (for Resin this is simply a matter of placing it in the top level lib directory). +

+More specifically, the SMB URL protocol handler (jcifs.smb.Handler) is used by the java.net.URL class to provide the Java "smb://" URL implementation. There are two possible reasons why this handler is not being recognized. +

    +
  1. +The current security policy is preventing jCIFS from setting the java.protocol.handler.pkgs system property which is required to install the SMB URL protocol handler. For example, some servlet containers install a security manager or restrictive policy file. In this case, add the jCIFS jar file to the container's CLASSPATH because servlet containers usually associate a policy file with the class files of web applications. Otherwise, the specific (minimum) grant required by jCIFS to successfully install the SMB URL protocol handler is: +
    +permission java.util.PropertyPermission "java.protocol.handler.pkgs", "read, write";
    +
    +If jCIFS is not permitted to write this system property, the SecurityException throw will be caught and a message will be printed to System.err. Alternatively the property can also be set using a VM command line parameter: +
    +java -Djava.protocol.handler.pkgs=jcifs ...
    +
    +This should permit the URL protocol handler to be installed regardless of what security policy is installed (however this isn't recommended as it will override other protocol handlers). +
  2. +The jCIFS jar file is not in a suitable location. Even if the java.protocol.handler.pkgs property is set successfully, the java.net.URL class must then access the jcifs.smb.Handler class. But if the jCIFS classes are loaded by a different class loader this handler will not be found and again, you will get the "unknown protocol: smb" exception. It is very common for servlet containers to load classes from a class loader other than the System class loader. Like the first scenario, the solution is to add the jCIFS jar file to the container's CLASSPATH and not the WEB-INF/lib directory of the web app. +
  3. +
+ + + +
+Q: I'm getting these UnknownHostExceptions right from the start. What am I doing wrong? +
+$ java List smb://server/share/
+Exception in thread "main" java.net.UnknownHostException: SERVER<20>
+        at jcifs.netbios.NbtAddress.doNameQuery(NbtAddress.java, Compiled Code)
+        at jcifs.netbios.NbtAddress.getByName(NbtAddress.java, Compiled Code)
+        at jcifs.smb.SmbFile.<init>(SmbFile.java, Compiled Code)
+        at jcifs.smb.SmbFile.<init>(SmbFile.java, Compiled Code)
+        at List.main(List.java, Compiled Code)
+
+

+A: In a nutshell, this is what happens when jCIFS cannot even find the target host. +

+For jCIFS to access another computer's files and services the target must be running a CIFS server over a NetBIOS LAN. This is exactly the case with 90% of MS Windows networks as CIFS over NetBIOS is MS's native networking setup. In this environment jCIFS should work flawlessly. However the above UnknownHostException is occurring because the name of the target computer cannot be resolved. There could be many reasons why this is happening. + +

Breakdown of Possible Name Resolution Problems:

+ +
+ +In general, if jCIFS is producing unwarranted UnknownHostExceptions, you will need to find out a little more about your network. Be sure to read the Setting Client Properties section from the API Documentation and pay close attention to the jcifs.netbios.wins property. Connecting to Windows machines on the local subnet should work even without setting the WINS property. To connect to a machine on another subnet you can use the IP address of the host (eg. smb://192.168.1.15/someshare/) or set the jcifs.netbios.wins property and use NetBIOS server names. Below are some diagnostics that might help. + +

Diagnosis:

+Personally I much prefer to take a packet capture when trying to diagnose networking issues. See Obtaining a Network Packet Capture for instructions on how to do that. +

+Otherwise, first check to see if your local hostname reverse-resolves properly. On UNIX you should look at your /etc/hosts file to make sure it's not mapped to 127.0.0.1. Otherwise just try pinging yourself. The below shows a problem. It should really be resolving to the real IP. +

+[miallen@nano jcifs]$ ping nano
+PING nano (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.    // 127.0.0.1 INCORRECT
+64 bytes from nano (127.0.0.1): icmp_seq=0 ttl=255 time=0.1 ms
+...
+[miallen@bogus jcifs]$ ping bogus
+PING bogus.research.ml.com (172.32.29.134) from 172.32.29.134 : 56(84) bytes of data. // Real IP is CORRECT
+64 bytes from bogus.research.ml.com (172.32.29.134): icmp_seq=1 ttl=255 time=0.090 ms
+
+ +There are many ways to test the machines on your network for the necessary NetBIOS name services. If you have a Windows machine available you can use nbtstat and ipconfig. On Linux and UNIX you can use ifconfig and nmblookup (nmblookup is from the Samba package). More specifically try: +
+C:\> ipconfig
+or
+C:\> ipconfig /all
+to confirm your IP address(e.g. 192.168.1.15) and then do:
+C:\> nbtstat -A 192.168.1.15
+
+You should get the netbios hostname of the machine as well as some other useful information. You can now do this on other hosts as well provided you know their IP addresses. If this is working and the necessary properties are set correctly jCIFS should work flawlessly. +

+The Samba suite has a similar tool that you can use on Linux and UNIX. Again, first verify your IP address with: +

+$ /sbin/ifconfig
+$ nmblookup -A 192.168.1.15
+
+If any of the above fails you need to look closer at your network settings or have a discussion with your network administrator. But if you determine that the NetBIOS service is in fact listening on the targets of interest you can use the net command on Windows, smbclient on Linux/UNIX, or jCIFS to test connecting to services: +
+C:\> net use * \\servername\share
+
+or on UNIX with +
+$ smbclient -L //servername
+$ smbclient //servername/share
+$ smbclient //servername/share -W research
+                            // -W required for domain auth
+
+If the above works the below List example (in the examples directory) should work as well. Try it with -Djcifs.util.loglevel=10 to see detailed log messages. +
+$ java -Djcifs.util.loglevel=10 List smb://server/share/
+
+ + + + +Q: Why do I get these "Network is unreachable" IOExceptions? +
+java.io.IOException: Network is unreachable
+at java.net.PlainDatagramSocketImpl.send(Native Method)
+at java.net.DatagramSocket.send(DatagramSocket.java, Compiled Code)
+at jcifs.netbios.NameServiceClient.send(NameServiceClient.java, Compiled Code)
+...
+
+ +A: +Most likely you need to set the broadcast address that jCIFS should use to broadcast name query requests. The Java Language does not provide a way to extract this information from a host so we simply try to use '255.255.255.255'. This will work with most network configurations, however this will fail under certain conditions producing the above exception. +

+To set the broadcast address, use the jcifs.netbios.baddr property such as adding jcifs.netbios.baddr=192.168.1.255 or similar to your properties or use -Djcifs.netbios.baddr=192.168.1.255 on the commandline. You can determine your proper broadcast address by running the ipconfig command on Windows or /sbin/ifconfig on Unix (Linux at least). See the Setting JCIFS Properties page for details. +

+C:\> ipconfig
+C:\> ipconfig /all
+or on Linux:
+$ /sbin/ifconfig
+
+Another cause of this is if your host does not have a suitable network interface over which to communicate (e.g. laptops with certain power management facilities can switch the NIC to powersave mode if theres nothing plugged into it). +

+ + + + +Q: How can I authenticate arbitrary user credentials from an application or web clients against Active Directory? +

+A: There are two ways to do this. One is to use the jcifs.smb.Session.logon() method to perform an SMB_COM_SESSION_SETUP_ANDX like: +

+UniAddress mydomaincontroller = UniAddress.getByName( "192.168.1.15" );
+NtlmPasswordAuthentication mycreds = new NtlmPasswordAuthentication( "ntdom", "user", "pass" );
+try {
+    SmbSession.logon( mydomaincontoller, mycreds );
+    // SUCCESS
+    return true;
+} catch( SmbAuthException sae ) {
+    // AUTHENTICATION FAILURE
+    return false;
+} catch( SmbException se ) {
+    // NETWORK PROBLEMS?
+    se.printStackTrace();
+}
+
+ +However, just like using an LDAP "bind" to validate credentials, the above method is a mild abuse of the protocol and can cause issues (e.g. with personal workstation AD security policy). The only way to properly validate NTLM credentials is with a NetrLogonSamLogon DCERPC call with the NETLOGON service. The only 100% Java solution that does that is Jespa. +
diff --git a/docs/httpclient.html b/docs/httpclient.html new file mode 100644 index 0000000..6c220bf --- /dev/null +++ b/docs/httpclient.html @@ -0,0 +1,203 @@ + + + + + + + + + +

Using JCIFS NTLM Authentication for HTTP Connections

+ +Using jCIFS, support for the NTLM authentication protocol can be added to HTTP connections. This functionality was added to Java 1.4.2 for Windows; jCIFS extends this feature to all supported platforms, as well as older Java environments. This allows Java-based HTTP clients to connect to web sites which use the "NTLM" or "Negotiate" authentication schemes, providing easy integration with domain user accounts. + +

+ + +Important: Sun's Java 1.4 for Windows has NTLM and Negotiate authentication support builtin. Because the JCIFS NtlmHttpURLConnection class is really just a wrapper for the default HTTP client, any authentication is intercepted by Sun's client thereby preventing JCIFS from be used to authenticate HTTP connections. If you wish to use the credentials of the current user you should not care but if alternative credentials are to be used, you will encounter this problem. Currently we do not know of a way to disable HTTP authentication in the Sun client. + +Note: This functionality is a non-conformant extension to HTTP conceived entirely by Microsoft. It inappropriately uses HTTP headers and therefore may not work with all Java environments or HTTP connection implementation. Also, this flavor of password encryption is not very secure so under no circumstances should it be used to authenticate clients on the Internet. + +

+ +Note: Currently, installing the jCIFS HTTP protocol handler will prevent HTTP PUT requests from working with or without NTLM HTTP authentication. + + +

Installation and Setup

+ +The jCIFS NTLM support is implemented as a URLStreamHandler for HTTP connections. This handler "wraps" the default handler provided by your Java environment to add support for NTLM authentication. There are two ways to install the handler: + +
    + +
  • + +Add the "jcifs" package to the list of protocol handler packages. +The "java.protocol.handler.pkgs" property is a pipe-separated ("|") list of packages which supply protocol handlers to Java. The "jcifs" package should be added to this list; this would typically be done by adding "-Djava.protocol.handler.pkgs=jcifs" to the command line when starting the application. +
  • + +
  • + +Register the handler using jcifs.Config.registerSmbURLHandler(). +As an alternative to the above, the static method registerSmbURLHandler in jcifs.Config will automatically install the jCIFS URL handlers. Note that this method must be called prior to creating HTTP URL objects. This would typically be done within the application's main method. +
  • + +
+ +After the handler is installed, NTLM support is transparently available to your application. To create a connection to an NTLM-protected site, you would simply do something like: + +
+URL myUrl = new URL("http://server/index.html");
+InputStream stream = myUrl.openStream();
+
+ +Authentication information is obtained from jCIFS properties (outlined below). Authentication information for a particular connection can also be explicitly provided within the URL itself, using the form: + +
+http://DOMAIN%5Cuser:password@server/index.html
+
+ + +

JCIFS Properties Meaningful to NTLM HTTP Clients

+ +The table below outlines the properties which directly affect the use of NTLM for HTTP connections. These can be passed via system properties, or set explicitly within an application using the jcifs.Config.setProperty method. These properties must be set before jCIFS classes are used. For a complete list of jCIFS properties refer to the overview page of the API documentation. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
http.auth.ntlm.domain + The default authentication domain in which the user is a member. + This is the property used by Sun's implementation of NTLM in JDK 1.4.2; + if set, it will override jcifs.smb.client.domain (to ensure + consistent operation across platforms). + This is only used if authentication information is not provided within + the URL itself. +
jcifs.smb.client.domain + The default authentication domain in which the user is a member. + This is used if authentication information is not provided within the + URL itself. +
jcifs.smb.client.username + The default username used if not specified within the URL itself. +
jcifs.smb.client.password + The default password used if not specified within the URL itself. +
jcifs.netbios.hostname + During NTLM authentication, the client's NetBIOS hostname is presented + to the server. This property can be used to specify a particular name. + If not provided, a generic name will be dynamically generated + (i.e. JCIFS35_177_E6). +
+ + +

Compatibility Notes

+ +The functionality provided requires that the underlying HTTP implementation +supports keep-alive connections. This has been tested successfully under Sun's +JDK 1.3.1_02, 1.3.1_06, 1.3.1_07, 1.4.0_01, and 1.4.2-beta. It is known NOT to +work on JDK 1.3, as well as the initial release of JDK 1.3.1. Results on other +JDK versions, as well as other vendor implementations, may vary. + +
+ + Last updated Mar 18, 2009
jcifs-1.3.7
+ Copyright © 2004 The JCIFS Project
+validate this page
+ + diff --git a/docs/httpclient.xml b/docs/httpclient.xml new file mode 100644 index 0000000..7b64d06 --- /dev/null +++ b/docs/httpclient.xml @@ -0,0 +1,100 @@ + + + +Using JCIFS NTLM Authentication for HTTP Connections + +Using jCIFS, support for the NTLM authentication protocol can be added to HTTP connections. This functionality was added to Java 1.4.2 for Windows; jCIFS extends this feature to all supported platforms, as well as older Java environments. This allows Java-based HTTP clients to connect to web sites which use the "NTLM" or "Negotiate" authentication schemes, providing easy integration with domain user accounts. + +

+ +Important: Sun's Java 1.4 for Windows has NTLM and Negotiate authentication support builtin. Because the JCIFS NtlmHttpURLConnection class is really just a wrapper for the default HTTP client, any authentication is intercepted by Sun's client thereby preventing JCIFS from be used to authenticate HTTP connections. If you wish to use the credentials of the current user you should not care but if alternative credentials are to be used, you will encounter this problem. Currently we do not know of a way to disable HTTP authentication in the Sun client. + +Note: This functionality is a non-conformant extension to HTTP conceived entirely by Microsoft. It inappropriately uses HTTP headers and therefore may not work with all Java environments or HTTP connection implementation. Also, this flavor of password encryption is not very secure so under no circumstances should it be used to authenticate clients on the Internet. +

+Note: Currently, installing the jCIFS HTTP protocol handler will prevent HTTP PUT requests from working with or without NTLM HTTP authentication. + +

Installation and Setup

+ +The jCIFS NTLM support is implemented as a URLStreamHandler for HTTP connections. This handler "wraps" the default handler provided by your Java environment to add support for NTLM authentication. There are two ways to install the handler: + +
    +
  • +Add the "jcifs" package to the list of protocol handler packages. +The "java.protocol.handler.pkgs" property is a pipe-separated ("|") list of packages which supply protocol handlers to Java. The "jcifs" package should be added to this list; this would typically be done by adding "-Djava.protocol.handler.pkgs=jcifs" to the command line when starting the application. +
  • +
  • +Register the handler using jcifs.Config.registerSmbURLHandler(). +As an alternative to the above, the static method registerSmbURLHandler in jcifs.Config will automatically install the jCIFS URL handlers. Note that this method must be called prior to creating HTTP URL objects. This would typically be done within the application's main method. +
  • +
+ +After the handler is installed, NTLM support is transparently available to your application. To create a connection to an NTLM-protected site, you would simply do something like: + +
+URL myUrl = new URL("http://server/index.html");
+InputStream stream = myUrl.openStream();
+
+ +Authentication information is obtained from jCIFS properties (outlined below). Authentication information for a particular connection can also be explicitly provided within the URL itself, using the form: + +
+http://DOMAIN%5Cuser:password@server/index.html
+
+ +

JCIFS Properties Meaningful to NTLM HTTP Clients

+ +The table below outlines the properties which directly affect the use of NTLM for HTTP connections. These can be passed via system properties, or set explicitly within an application using the jcifs.Config.setProperty method. These properties must be set before jCIFS classes are used. For a complete list of jCIFS properties refer to the overview page of the API documentation. + +

+ + + + + + + + + + + + + + + + + + + + + +
http.auth.ntlm.domain + The default authentication domain in which the user is a member. + This is the property used by Sun's implementation of NTLM in JDK 1.4.2; + if set, it will override jcifs.smb.client.domain (to ensure + consistent operation across platforms). + This is only used if authentication information is not provided within + the URL itself. +
jcifs.smb.client.domain + The default authentication domain in which the user is a member. + This is used if authentication information is not provided within the + URL itself. +
jcifs.smb.client.username + The default username used if not specified within the URL itself. +
jcifs.smb.client.password + The default password used if not specified within the URL itself. +
jcifs.netbios.hostname + During NTLM authentication, the client's NetBIOS hostname is presented + to the server. This property can be used to specify a particular name. + If not provided, a generic name will be dynamically generated + (i.e. JCIFS35_177_E6). +
+ +

Compatibility Notes

+ +The functionality provided requires that the underlying HTTP implementation +supports keep-alive connections. This has been tested successfully under Sun's +JDK 1.3.1_02, 1.3.1_06, 1.3.1_07, 1.4.0_01, and 1.4.2-beta. It is known NOT to +work on JDK 1.3, as well as the initial release of JDK 1.3.1. Results on other +JDK versions, as well as other vendor implementations, may vary. + +
diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..a7eba3c --- /dev/null +++ b/docs/index.html @@ -0,0 +1,504 @@ + + + + + +JCIFS + + + + + + + + + + + + +
+
+JCIFS

The Java CIFS Client Library

+
+

+JCIFS is an Open Source client library that implements the CIFS/SMB networking protocol in 100% Java. CIFS is the standard file sharing protocol on the Microsoft Windows platform (e.g. Map Network Drive ...). This client is used extensively in production on large Intranets. +
+

Links

+Download +
+JCIFS NTLM HTTP Authentication +
+The FAQ +
+Mailing List Archive (GMANE) +
+Obtaining a Network Packet Capture +
+

Developer Information

+JCIFS API Documentation +
+Setting Client Properties +
+Setting Name Resolution Properties +
+Using JCIFS to Connect to Win32 Named Pipes +
+JCIFS Exceptions and NtlmAuthenticator +
+Using JCIFS NTLM Authentication for HTTP Connections +
+JCIFS is Licensed Under the LGPL +
+

Related Java Projects

+j-interop - Java COM Interop (uses Jarapac) +
+sharehound - CIFS network search engine +
+IntegraTUM WebDisk - HTTP to CIFS gateway +
+jcifs-ext - JCIFS Extensions +
+Jarapac - DCE/RPC in Java +
+The Jacob Project - Java/COM Bridge +
+JNBridge - Java/.NET Bridge +
+J-Integra - DCE/RPC in Java +
+Davenport - WebDAV to CIFS gateway +
+Alfresco JLAN Shared File Drive Interface +
+

CIFS Authorities

+http://www.samba.org/ +
+http://www.samba-tng.org/ +
+

Other CIFS Utilities and Tools

+Samba for Amiga +
+Sharity-Lite +
+SMB Browse for MacOSX +
+Xamba Network Integration Project +
+

MSRPC

+Rpcdump utility for querying RPC servers +
+OpenGroup DCE/RPC Specification +
+OpenGroup DCE/RPC Specification - NDR +
+What OLE Is Really About +
+

Kerberos

+RFC1510 - Kerberos V5 Specification +
+How a Kerberos Logon Works in Win2K +
+JGSS Example +
+Kerberos Explained +
+W2K PAC Specification +
+

Technical Documentation

+"Implementing CIFS" (complete online book) +
+Annotated CIFS Specification: draft-leach-cifs-v1-spec-02.html +
+SNIA CIFS Technical Reference (V1.0) +
+The NTLM Authentication Protocol +
+A .NET Developer's Guide to Windows Security +
+Windows System Error Codes +
+Windows Network Management Error Codes +
+rfc1001 - NetBIOS Concepts and Methods +
+rfc1002 - NetBIOS Detailed Specifications +
+CIFS Explained (A whitepaper by John Kleven) +
+SMB URL draft specification V07 +
+NetBIOS, NetBEUI, NBF, SMB, CIFS networking links page +
+Microsoft Writeup on WINS behavior +
+Microsoft Writeup on WINS under W2K +
+Microsoft Server Documentation on Browsing WANs using WINS +
+Windows IT Library: NT Network Plumbing +
+Thursby Software's CIFS pages +
+Linux Mag: Understanding the Network Neighborhood +
+

Other

+Join the JCIFS Mailing List +
+Browse the Source +
+Batching +
+http://www.gnu.org/ +
+http://www.opensource.org/ +
+Microsoft's CIFS Mailing List Archives +
+
+

News

+jcifs-1.3.14 released / NetBIOS Node Status Disabled and Named Pipe Errors +
+posted by Mike, February 11, 2010 +
+JCIFS will no longer do a NetBIOS Node Status to determine the server hostname because it seems some servers no longer respond to it. Under high load "All pipe instances are busy" errors could occur. This has been fixed by adding a lock to ensure that the MSRPC bind and pipe open request are performed together. +

+jcifs-1.3.13 released / Deadlock Fixed, OSX Snow Leopard, and EMC +
+posted by Mike, January 5, 2010 +
+Locking throughout the transport layer has been rewritten. This should fix the long standing deadlock that has been reported in the past. Note that these are significant changes to the I/O layer. The package should be tested carefully before being deployed. +

The size of the transient input buffer used to read the SMB_COM_NEGOTIATE response has been doubled to accommodate a security blob (as observed with OSX Snow Leopard). A signing issue reading data from an EMC server has been fixed. NTLMSSP logging has been improved. +

+The JCIFS Team would like to thank Stoneware, Inc. for supporting this work. Stoneware, Inc. provides innovative software that enables organizations to build their own 'private' cloud for simplified access to all of their web, Windows or hosted applications and services. +

+JCIFS U.S. Export Control Classification Numbers (ECCN) +
+posted by Mike, August 27, 2009 +
+JCIFS uses cryptography including RC4 128 (for NTLMv2) and AES 256 (for Kerberos) for authentication, digital signatures and encryption. +Products that use cryptography and which are exported from the U.S. to other countries are supposed to obtain an export classification. +The United States Department of Commerce Bureau of Industry and Security (BIS) has issued two ECCNs for the JCIFS package: +
+5D002.C.1 License Exception TSU
+5D992.C (for binary only distribution of "mass market" software) +
+For commercial products that ship JCIFS in binary form, you will need to reference the second ECCN in your export classification requests. +For further information such as CCATS numbers, please contact ioplex@gmail.com. +

+The JCIFS Team would like to thank BIS for there excellent service and patience. +

+jcifs-1.3.12 released / Two NullPointerExceptions Fixed and DFS +
+posted by Mike, August 14, 2009 +
+If NtlmPasswordAuthentication.ANONYMOUS was used, CAP_EXTENDED_SECURITY could be incorrectly turned off resulting in a NullPointerException. If a DFS server did not return any referrals, a NullPointerException could occur. Both of these exceptions have been corrected. Also, JCIFS could become confused when connecting to a server that also happened to be a DFS root server. This issue has been fixed. +

+jcifs-1.3.11 released / NTLMv2 Calculation Correction +
+posted by Mike, July 21, 2009 +
+The nTOWFv2 computation for NTLMv2 authentication was slightly wrong in that it upper-cased the domain. This had no effect on JCIFS but it has been corrected for technical accuracy. +

+jcifs-1.3.10 released / Bugfix for SmbException: The parameter is incorrect +
+posted by Mike, June 4, 2009 +
+This release fixes a bug that could sporadically trigger a "The parameter is incorrect" error. +

+The JCIFS Team would like to thank IOPLEX Software for contributing to this work. +IOPLEX Software has many years of experience with HTTP Single Sign-On, Kerberos, NTLM, Active Directory, MSRPC and related networking protocols. +

+jcifs-1.3.9 released / Robust Retry of Replicated DFS Targets, copyTo Fix, UTF-16LE, and More +
+posted by Mike, May 30, 2009 +
+This package adds the following fixes: +
    + +
  • +JCIFS will now iteratively try multiple replicated DFS targets if some are not enabled (whereas previously JCIFS would quit if the first root target was not accessible) +
  • + +
  • +Fixed "Invalid operation for ????? service" error when querying DFS +
  • + +
  • +SmbFile.copyTo will now copy files larger than 4GB +
  • + +
  • +All instances of UnicodeLittleUnmarked have been changed to UTF-16LE (for platforms like Android) +
  • + +
+ +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. +

+jcifs-1.3.8 released / RC4 Implemented, Java 1.4 Now Supported Again +
+posted by Mike, Mar 29, 2009 +
+RC4 has been implemented and therefore JCIFS no longer requires Java 1.5 update 7 or an implementation that provides RC4. Java 1.4 should work as well as it did prior to JCIFS 1.3. +

+jcifs-1.3.7 released / Share Security Fixed +
+posted by Mike, Mar 18, 2009 +
+Share security was broken in both 1.2 and 1.3. It has been fixed. Note that share security is considered deprecated and is only supported by older software like Windows 98 and Samba 3.0. +

+jcifs-1.3.5 released / Stand-alone DFS with IP Address Hostname Issue Fixed +
+posted by Mike, Mar 12, 2009 +
+Stand-alone DFS did not work properly if the hostname used in the SMB URL was an IP address and not a DNS or NetBIOS hostname. This issue has been fixed. +

+The JCIFS Team would like to thank Vivísimo, Inc. for supporting this work. Vivísimo provides enterprises with innovative search solutions to find, access, and manipulate all content. For consumer web searches, Vivísimo offers Clusty.com. +

+jcifs-1.3.4 released / Parameter Words, Status Codes and Minor Fixes +
+posted by Mike, Mar 9, 2009 +
+This release includes some minor protocol adjustments and the addition of some more common status code text. +

+jcifs-1.3.3 released / NTLMv2 Requirements, "Invalid parameter" Error, and NetBIOS Broadcast Lookup Timeouts +
+posted by Mike, Jan 25, 2009 +
+NTLMv2 support requires the RC4 cipher. Note that Sun's Java did not include RC4 until Java 1.5 update 7. +

+If the above mentioned RC4 cipher was not available, an "Invalid parameter" error would occur. Logic has been corrected so that the more informative "Cannot find any provider supporting RC4" error is reported instead. +

+To date, JCIFS has always tried NetBIOS broadcast lookups in favor of DNS which frequently resulted in a 6 second delay if the jcifs.resolveOrder property was not adjusted. This behavior has been changed to try DNS before NetBIOS broadcast lookups which should result in much less frequent delays when using default settings. To restore the old behavior, simply set jcifs.resolveOrder=LMHOSTS,BCAST,DNS. +

+The NTLMSSP code would not fallback to ASCII if Cp850 was not available (which is the case with stock JREs). This issue has been fixed. +

+jcifs-krb5-1.3.1 released / Kerberos 5 Package Updated +
+posted by Mike, Dec 22, 2008 +
+The Kerberos package been updated to 1.3.1. The KerberosAuthExample.java example has been independently verified to work. Special thanks to Mr. Shun for contributing this package. +

+jcifs-1.3.2 released / Samba DFS +
+posted by Mike, Dec 22, 2008 +
+Accessing a DFS link on Samba directly could result in an error. This issue has been fixed. Samba 3.0.x does not support raw NTLMSSP and therefore the new default JCIFS settings that use NTLMSSP break JCIFS and Samba 3.0.x compatibility. To work-around, turn off extended security and use NTLMv1 by setting jcifs.smb.client.useExtendedSecurity=false and jcifs.smb.lmCompatibility=0. +

+jcifs-1.3.1 released / NTLM HTTP Filter Fixed, DFS Adjustments and More +
+posted by Mike, Nov 30, 2008 +
+The NTLM HTTP Filter was broken in 1.3.0. Setting jcifs.smb.client.useExtendedSecurity to false fixes the issue. This property has been changed in the Filter init method. Some minor DFS changes have been applied that users claim prevent issues in certain DFS scenarios. The NTLMv2 code has been refined in several ways (in particular the getNTLMv2Response method has changed). The NtlmPasswordAuthentication constructor will now split the username if it appears to be composed of a domain and username. +

+jcifs-1.3.0 released / NTLMv2 Support +
+posted by Mike, Oct 25, 2008 +
+NTLMv2 has been fully implemented and will be used by default. +

+To emulate the old behavior you must set jcifs.lmCompatibility = 0 and jcifs.smb.client.useExtendedSecurity = false (new defaults are 3 and true respectively). +

+NTLMv2 and NTLMv1 over NTLMSSP has been fairly well tested with and without SMB signing negotiated and various NTLMSSP flags (e.g. NTLMSSP_NEGOTIATE_NTLM2). +

+Note: The NTLM HTTP Filter does not and can never support NTLMv2 as it uses a main-in-the-middle technique that is broken by NTLMSSP's "target information" used in computing password hashes. However, the existing Filter should continue to work. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. +

+jcifs-1.2.25 released / ArrayIndexOutOfBoundsException, copyTo and IBM iSeries Fixes +
+posted by Mike, Oct 20, 2008 +
+An ArrayIndexOutOfBoundsException could occur listing a large number of shares (DCERPC response larger than 65535 bytes). The copyTo method could deadlock if the server was disconnected during a copy. The IBM iSeries server can send the NativeFileSystem field in ASCII even though Unicode was negotiated and it requires the '?????' service string (and not 'A:'). These issues have been fixed. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. +

+jcifs-1.2.18 released / DCERPC, Robust Recovery, URL Decoding, NPEs and Much More +
+posted by Mike, Feb 18, 2008 +
+This release includes a few significant fixes for DCERPC related issues. It also includes numerous minor fixes for issues that have accumulated over time. The issues that have been fixed are as follows: + +
    + +
  • +The SID.getServerSid() method could fail with NetApp servers due to a "generic" mask values. The mask has been changed to 0x00000001 which corresponds to an LsaOpenPolicy mask of POLICY_VIEW_LOCAL_INFORMATION. +
  • +
  • +The LsaPolicyHandle class would not throw an error if the LsarOpenPolicy2 call failed. This has been fixed. +
  • +
  • +If a share was unshared while JCIFS was in the middle of reading files from it, the transport could enter an error state from which it could not immediately recover if the share was subsequently restored. A small change to SmbTransport.doRecv() fixes this problem. +
  • +
  • +The SmbFile constructor could inappropriately URL decode the authority component of SMB URLs. +
  • +
  • +The NTLM HTTP Filter documentation has been updated. +
  • +
  • +An Invalid state: 4 error has been fixed. +
  • +
  • +A NetBIOS name service issue caused by Jetdirect printers has been fixed. +
  • +
  • +An ArrayIndexOutOfBounds exception in the SmbException class has been fixed. +
  • +
  • +A NullPointerException in SmbSession.getChallengeForDomain() has been fixed. +
  • +
  • +A NullPointerException in NbtAddress related to hosts without adequate localhost address configuration has been fixed. +
  • +
  • +An ArrayIndexOutOfBounds exception could be thrown if a server requires NTLMv2. This exception has been replaced with a more informative one. +
  • +
  • +The SmbSessionSetup constructor will now compare the challenge and encryptionKey using Arrays.equals instead of == to satisfy unforseen use-cases that otherwise trigger an NT_STATUS_ACCESS_VIOLATION. +
  • + +
+ +The JCIFS Team would like to thank Vivísimo, Inc. for supporting this work. Vivísimo provides enterprises with innovative search solutions to find, access, and manipulate all content. For consumer web searches, Vivísimo offers Clusty.com. +

+The JCIFS Team would like to thank IOPLEX Software for contributing to this work. +IOPLEX Software has many years of experience with HTTP Single Sign-On, Kerberos, NTLM, Active Directory, MSRPC and related networking protocols. +IOPLEX Software's Plexcel extension for PHP provides unmatched integration with Active Directory for PHP applications. +

+Alfresco releases Java CIFS server under GPL +
+posted by Mike, Nov 2, 2007 +
+ +Alfresco have announced the release of the JLAN Shared File Drive Interface under the terms of the Gnu General Public License (GPL). JLAN includes a CIFS server written in Java, as well as several other Java-based network components. +

+"I am very excited about this Open Source contribution", said Chris Hertel, Samba Team member and co-founder the jCIFS project. "Every Open Source CIFS implementation adds to the community's understanding, and to the utility of the protocol itself." +

Their press release has a link to the source code at the bottom of the page. +

+jcifs-1.2.16 released / Domain-Based DFS Support +
+posted by Mike, Aug 2, 2007 +
+With this release, JCIFS now supports domain-based DFS. With domain-based DFS, clients access DFS roots under the DNS domain name like \\example.com\dfs\foo so that users do not need to remember server names. However, for clients to work with these DFS roots they have to be prepared to connect to each domain controller as necessary to find the target share and successfully authenticate. JCIFS now includes this retry logic. JCIFS will also do something that it seems even Windows clients do not do - if you list the shares of a domain (e.g. (new SmbFile("smb://example.com/")).listFiles()), JCIFS will build a merged list of all shares on all domain controllers. +

+Note that these changes are fairly significant. Whenever JCIFS tries to connect to a server this new logic is used. So if anyone notices anything out of the ordinary please report it to the JCIFS mailing list. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. +

+jcifs-1.2.15 released / NetApp Compatibility, SMB signing with DFS and More +
+posted by Mike, Jul 16, 2007 +
+This release includes some significant changes. Most of these changes are related to NetApp compatibility. The changes in this release include the following: +
    + +
  • An SMB signing failure related to DFS that could result in "Access denied" errors has been fixed.
  • + +
  • The DCERPC bind did not exactly mimic Windows which uses SMB_COM_{WRITE,READ}_ANDX. We were using TransactNmPipe throughout which could result in an 'Incorrect function' error when querying the LSA on a NetApp server. JCIFS now implements the bind exactly like Windows to help ensure compatibility with other servers.
  • + +
  • Other changes related to NetApp compatibility include falling back to SamrConnect2 if a DCERPC_FAULT_OP_RNG_ERROR error occurs, more closely mimicking the SMB_COM_NT_CREATE_ANDX "extended" response, adjusting various RPC handle operation access masks, uncommenting some padding code that was commented out for what appeared to be a NetWare problem, disabling some logic to use port 139 if the jcifs.netbios.hostname was set and finally adding code to include LsarQosInfo structures in the MSRPC bind.
  • + +
  • Some new error code information has been added.
  • + +
  • Constants for common SIDs have been added to the SID class.
  • + +
  • The SID.getGroupMemberSids() method will now return an empty SID array if the SID is not of type SID_TYPE_DOM_GRP or SID_TYPE_ALIAS.
  • + +
  • A minor performance flaw in the DCERPC code was found and fixed.
  • + +
+ +

+The JCIFS Team would like to thank Simple Groupware Solutions and the Leibniz Computing Centre Munich (LRZ) for supporting this work. +

+The JCIFS Team would like to thank Vivísimo, Inc. for supporting this work. Vivísimo provides enterprises with innovative search solutions to find, access, and manipulate all content. For consumer web searches, Vivísimo offers Clusty.com. +

+jcifs-krb5-1.2.13 released / Kerberos Authentication Support Update +
+posted by Mike, Feb 8, 2007 +
+The stock jcifs-1.2.13 package has been patched by a third party to support Kerberos 5 / SPNEGO extended security authentication. Additionally, SMB signing and DFS issues that existed in jcifs-krb5-1.2.9 have been fixed. +

+The JCIFS team has compiled the package and confirmed that it works with at least the one test case provided (examples/KerberosAuthExample.java) but otherwise the code should be used with caution. +

+Great thanks again to Mr. Shun from Japan for contributing this work. +

+
+ + diff --git a/docs/index.xml b/docs/index.xml new file mode 100644 index 0000000..3225e40 --- /dev/null +++ b/docs/index.xml @@ -0,0 +1,2670 @@ + + + + +JCIFS +The Java CIFS Client Library + +JCIFS is an Open Source client library that implements the CIFS/SMB networking protocol in 100% Java. CIFS is the standard file sharing protocol on the Microsoft Windows platform (e.g. Map Network Drive ...). This client is used extensively in production on large Intranets. + + + + + + +jcifs-1.3.14 released / NetBIOS Node Status Disabled and Named Pipe Errors +posted by Mike, February 11, 2010 + +JCIFS will no longer do a NetBIOS Node Status to determine the server hostname because it seems some servers no longer respond to it. Under high load "All pipe instances are busy" errors could occur. This has been fixed by adding a lock to ensure that the MSRPC bind and pipe open request are performed together. + + + + +jcifs-1.3.13 released / Deadlock Fixed, OSX Snow Leopard, and EMC +posted by Mike, January 5, 2010 + +Locking throughout the transport layer has been rewritten. This should fix the long standing deadlock that has been reported in the past. Note that these are significant changes to the I/O layer. The package should be tested carefully before being deployed. +

The size of the transient input buffer used to read the SMB_COM_NEGOTIATE response has been doubled to accommodate a security blob (as observed with OSX Snow Leopard). A signing issue reading data from an EMC server has been fixed. NTLMSSP logging has been improved. +

+The JCIFS Team would like to thank Stoneware, Inc. for supporting this work. Stoneware, Inc. provides innovative software that enables organizations to build their own 'private' cloud for simplified access to all of their web, Windows or hosted applications and services. + + + + +JCIFS U.S. Export Control Classification Numbers (ECCN) +posted by Mike, August 27, 2009 + +JCIFS uses cryptography including RC4 128 (for NTLMv2) and AES 256 (for Kerberos) for authentication, digital signatures and encryption. +Products that use cryptography and which are exported from the U.S. to other countries are supposed to obtain an export classification. +The United States Department of Commerce Bureau of Industry and Security (BIS) has issued two ECCNs for the JCIFS package: +

+5D002.C.1 License Exception TSU
+5D992.C (for binary only distribution of "mass market" software) +
+For commercial products that ship JCIFS in binary form, you will need to reference the second ECCN in your export classification requests. +For further information such as CCATS numbers, please contact ioplex@gmail.com. +

+The JCIFS Team would like to thank BIS for there excellent service and patience. + + + + +jcifs-1.3.12 released / Two NullPointerExceptions Fixed and DFS +posted by Mike, August 14, 2009 + +If NtlmPasswordAuthentication.ANONYMOUS was used, CAP_EXTENDED_SECURITY could be incorrectly turned off resulting in a NullPointerException. If a DFS server did not return any referrals, a NullPointerException could occur. Both of these exceptions have been corrected. Also, JCIFS could become confused when connecting to a server that also happened to be a DFS root server. This issue has been fixed. + + + + +jcifs-1.3.11 released / NTLMv2 Calculation Correction +posted by Mike, July 21, 2009 + +The nTOWFv2 computation for NTLMv2 authentication was slightly wrong in that it upper-cased the domain. This had no effect on JCIFS but it has been corrected for technical accuracy. + + + + +jcifs-1.3.10 released / Bugfix for SmbException: The parameter is incorrect +posted by Mike, June 4, 2009 + +This release fixes a bug that could sporadically trigger a "The parameter is incorrect" error. +

+The JCIFS Team would like to thank IOPLEX Software for contributing to this work. +IOPLEX Software has many years of experience with HTTP Single Sign-On, Kerberos, NTLM, Active Directory, MSRPC and related networking protocols. + + + + +jcifs-1.3.9 released / Robust Retry of Replicated DFS Targets, copyTo Fix, UTF-16LE, and More +posted by Mike, May 30, 2009 + +This package adds the following fixes: +

    +
  • +JCIFS will now iteratively try multiple replicated DFS targets if some are not enabled (whereas previously JCIFS would quit if the first root target was not accessible) +
  • +
  • +Fixed "Invalid operation for ????? service" error when querying DFS +
  • +
  • +SmbFile.copyTo will now copy files larger than 4GB +
  • +
  • +All instances of UnicodeLittleUnmarked have been changed to UTF-16LE (for platforms like Android) +
  • +
+

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. + + + + +jcifs-1.3.8 released / RC4 Implemented, Java 1.4 Now Supported Again +posted by Mike, Mar 29, 2009 + +RC4 has been implemented and therefore JCIFS no longer requires Java 1.5 update 7 or an implementation that provides RC4. Java 1.4 should work as well as it did prior to JCIFS 1.3. + + + + +jcifs-1.3.7 released / Share Security Fixed +posted by Mike, Mar 18, 2009 + +Share security was broken in both 1.2 and 1.3. It has been fixed. Note that share security is considered deprecated and is only supported by older software like Windows 98 and Samba 3.0. + + + + +jcifs-1.3.5 released / Stand-alone DFS with IP Address Hostname Issue Fixed +posted by Mike, Mar 12, 2009 + +Stand-alone DFS did not work properly if the hostname used in the SMB URL was an IP address and not a DNS or NetBIOS hostname. This issue has been fixed. +

+The JCIFS Team would like to thank Vivísimo, Inc. for supporting this work. Vivísimo provides enterprises with innovative search solutions to find, access, and manipulate all content. For consumer web searches, Vivísimo offers Clusty.com. + + + + +jcifs-1.3.4 released / Parameter Words, Status Codes and Minor Fixes +posted by Mike, Mar 9, 2009 + +This release includes some minor protocol adjustments and the addition of some more common status code text. + + + + +jcifs-1.3.3 released / NTLMv2 Requirements, "Invalid parameter" Error, and NetBIOS Broadcast Lookup Timeouts +posted by Mike, Jan 25, 2009 + +NTLMv2 support requires the RC4 cipher. Note that Sun's Java did not include RC4 until Java 1.5 update 7. +

+If the above mentioned RC4 cipher was not available, an "Invalid parameter" error would occur. Logic has been corrected so that the more informative "Cannot find any provider supporting RC4" error is reported instead. +

+To date, JCIFS has always tried NetBIOS broadcast lookups in favor of DNS which frequently resulted in a 6 second delay if the jcifs.resolveOrder property was not adjusted. This behavior has been changed to try DNS before NetBIOS broadcast lookups which should result in much less frequent delays when using default settings. To restore the old behavior, simply set jcifs.resolveOrder=LMHOSTS,BCAST,DNS. +

+The NTLMSSP code would not fallback to ASCII if Cp850 was not available (which is the case with stock JREs). This issue has been fixed. + + + + +jcifs-krb5-1.3.1 released / Kerberos 5 Package Updated +posted by Mike, Dec 22, 2008 + +The Kerberos package been updated to 1.3.1. The KerberosAuthExample.java example has been independently verified to work. Special thanks to Mr. Shun for contributing this package. + + + + +jcifs-1.3.2 released / Samba DFS +posted by Mike, Dec 22, 2008 + +Accessing a DFS link on Samba directly could result in an error. This issue has been fixed. Samba 3.0.x does not support raw NTLMSSP and therefore the new default JCIFS settings that use NTLMSSP break JCIFS and Samba 3.0.x compatibility. To work-around, turn off extended security and use NTLMv1 by setting jcifs.smb.client.useExtendedSecurity=false and jcifs.smb.lmCompatibility=0. + + + + +jcifs-1.3.1 released / NTLM HTTP Filter Fixed, DFS Adjustments and More +posted by Mike, Nov 30, 2008 + +The NTLM HTTP Filter was broken in 1.3.0. Setting jcifs.smb.client.useExtendedSecurity to false fixes the issue. This property has been changed in the Filter init method. Some minor DFS changes have been applied that users claim prevent issues in certain DFS scenarios. The NTLMv2 code has been refined in several ways (in particular the getNTLMv2Response method has changed). The NtlmPasswordAuthentication constructor will now split the username if it appears to be composed of a domain and username. + + + + +jcifs-1.3.0 released / NTLMv2 Support +posted by Mike, Oct 25, 2008 + +NTLMv2 has been fully implemented and will be used by default. +

+To emulate the old behavior you must set jcifs.lmCompatibility = 0 and jcifs.smb.client.useExtendedSecurity = false (new defaults are 3 and true respectively). +

+NTLMv2 and NTLMv1 over NTLMSSP has been fairly well tested with and without SMB signing negotiated and various NTLMSSP flags (e.g. NTLMSSP_NEGOTIATE_NTLM2). +

+Note: The NTLM HTTP Filter does not and can never support NTLMv2 as it uses a main-in-the-middle technique that is broken by NTLMSSP's "target information" used in computing password hashes. However, the existing Filter should continue to work. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. + + + + +jcifs-1.2.25 released / ArrayIndexOutOfBoundsException, copyTo and IBM iSeries Fixes +posted by Mike, Oct 20, 2008 + +An ArrayIndexOutOfBoundsException could occur listing a large number of shares (DCERPC response larger than 65535 bytes). The copyTo method could deadlock if the server was disconnected during a copy. The IBM iSeries server can send the NativeFileSystem field in ASCII even though Unicode was negotiated and it requires the '?????' service string (and not 'A:'). These issues have been fixed. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. + + + + +jcifs-1.2.24 released / Stand-Alone DFS Fixed +posted by Mike, Jul 23, 2008 + +The recent domain-based DFS work broke stand-alone DFS. This has been fixed. Both stand-alone and domain-based DFS should work properly now. +

+Note: The 1.2.23 was a dud - it did not really contain the said fix. + + + + +jcifs-1.2.22 released / InterruptedIOExceptions, Invalid parameter Exceptions, DFS and more +posted by Mike, Jun 25, 2008 + +The SmbFileInputStream methods will now throw InterruptedIOExceptions where apppropriate whereas previously they would throw SmbExceptions with a root cause of TransportException with a root cause of InterruptedException. +

+If SmbSession.send() threw an exception it could trigger "Invalid parameter" exceptions on subsequent requests. +

+An InterruptedException in the NameServiceClient was being caught and ignored. It will now be re-thrown as an IOException so that all threads used with/by JCIFS can be triggered to return immediately. +

+A jcifs.smb.client.dfs.disabled property has been added to disable domain based DFS so that JCIFS can be configured not to try and fail to resolve paths as domain paths in non-domain environments (e.g. on the local machine). +

+The getSecurity and getShareSecurity methods will now return null if no DACL is present on a file whereas previously it would return an empty array. This allows the caller to distinguish between an object that has a DACL with no elements and one that has no DACL at all. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. + + + + +jcifs-1.2.21 released / DFS Cache Bugfix +posted by Mike, May 28, 2008 + +The DFS cache was not properly synchronized. This has been fixed. +The trusted domains are now looked up with <1C> NetBIOS lookups to speed discovery. +

+Thanks to Ronny S. for reporting these issues. +

+ + + + +jcifs-1.2.19 released / DFS Roots on non-Domain Controllers +posted by Mike, Apr 6, 2008 + +This release adds proper support for domain based DFS roots. Previously JCIFS could not see DFS roots that were not hosted on domain controllers. JCIFS will now properly discover and cache DFS topology information using a series of referrals. +The new code also eliminates the now-obsolete behavior of building a merged list of shares across hosts. +A new NetrDfsEnumEx RPC has been added. +Two new properties have been added: jcifs.smb.client.dfs.ttl and jcifs.smb.client.dfs.strictView. +Two SmbComOpenAndX parameters were incorrectly swapped which could cause failure on Windows 98. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. + + + + +jcifs-1.2.18 released / DCERPC, Robust Recovery, URL Decoding, NPEs and Much More +posted by Mike, Feb 18, 2008 + +This release includes a few significant fixes for DCERPC related issues. It also includes numerous minor fixes for issues that have accumulated over time. The issues that have been fixed are as follows: + +

    +
  • +The SID.getServerSid() method could fail with NetApp servers due to a "generic" mask values. The mask has been changed to 0x00000001 which corresponds to an LsaOpenPolicy mask of POLICY_VIEW_LOCAL_INFORMATION. +
  • +The LsaPolicyHandle class would not throw an error if the LsarOpenPolicy2 call failed. This has been fixed. +
  • +If a share was unshared while JCIFS was in the middle of reading files from it, the transport could enter an error state from which it could not immediately recover if the share was subsequently restored. A small change to SmbTransport.doRecv() fixes this problem. +
  • +The SmbFile constructor could inappropriately URL decode the authority component of SMB URLs. +
  • +The NTLM HTTP Filter documentation has been updated. +
  • +An Invalid state: 4 error has been fixed. +
  • +A NetBIOS name service issue caused by Jetdirect printers has been fixed. +
  • +An ArrayIndexOutOfBounds exception in the SmbException class has been fixed. +
  • +A NullPointerException in SmbSession.getChallengeForDomain() has been fixed. +
  • +A NullPointerException in NbtAddress related to hosts without adequate localhost address configuration has been fixed. +
  • +An ArrayIndexOutOfBounds exception could be thrown if a server requires NTLMv2. This exception has been replaced with a more informative one. +
  • +The SmbSessionSetup constructor will now compare the challenge and encryptionKey using Arrays.equals instead of == to satisfy unforseen use-cases that otherwise trigger an NT_STATUS_ACCESS_VIOLATION. +
  • +
+ +The JCIFS Team would like to thank Vivísimo, Inc. for supporting this work. Vivísimo provides enterprises with innovative search solutions to find, access, and manipulate all content. For consumer web searches, Vivísimo offers Clusty.com. +

+The JCIFS Team would like to thank IOPLEX Software for contributing to this work. +IOPLEX Software has many years of experience with HTTP Single Sign-On, Kerberos, NTLM, Active Directory, MSRPC and related networking protocols. +IOPLEX Software's Plexcel extension for PHP provides unmatched integration with Active Directory for PHP applications. + + + + +Alfresco releases Java CIFS server under GPL +posted by Mike, Nov 2, 2007 + +Alfresco have announced the release of the JLAN Shared File Drive Interface under the terms of the Gnu General Public License (GPL). JLAN includes a CIFS server written in Java, as well as several other Java-based network components. +

+"I am very excited about this Open Source contribution", said Chris Hertel, Samba Team member and co-founder the jCIFS project. "Every Open Source CIFS implementation adds to the community's understanding, and to the utility of the protocol itself." +

Their press release has a link to the source code at the bottom of the page. + + + + +jcifs-1.2.17 released / Minor Fix +posted by Mike, Aug 15, 2007 + +A try / catch clause that was accidentally introduced in a previous release has been removed. + + + + +jcifs-1.2.16 released / Domain-Based DFS Support +posted by Mike, Aug 2, 2007 + +With this release, JCIFS now supports domain-based DFS. With domain-based DFS, clients access DFS roots under the DNS domain name like \\example.com\dfs\foo so that users do not need to remember server names. However, for clients to work with these DFS roots they have to be prepared to connect to each domain controller as necessary to find the target share and successfully authenticate. JCIFS now includes this retry logic. JCIFS will also do something that it seems even Windows clients do not do - if you list the shares of a domain (e.g. (new SmbFile("smb://example.com/")).listFiles()), JCIFS will build a merged list of all shares on all domain controllers. +

+Note that these changes are fairly significant. Whenever JCIFS tries to connect to a server this new logic is used. So if anyone notices anything out of the ordinary please report it to the JCIFS mailing list. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. + + + + +jcifs-1.2.15 released / NetApp Compatibility, SMB signing with DFS and More +posted by Mike, Jul 16, 2007 + +This release includes some significant changes. Most of these changes are related to NetApp compatibility. The changes in this release include the following: +

    +
  • An SMB signing failure related to DFS that could result in "Access denied" errors has been fixed.
  • +
  • The DCERPC bind did not exactly mimic Windows which uses SMB_COM_{WRITE,READ}_ANDX. We were using TransactNmPipe throughout which could result in an 'Incorrect function' error when querying the LSA on a NetApp server. JCIFS now implements the bind exactly like Windows to help ensure compatibility with other servers.
  • +
  • Other changes related to NetApp compatibility include falling back to SamrConnect2 if a DCERPC_FAULT_OP_RNG_ERROR error occurs, more closely mimicking the SMB_COM_NT_CREATE_ANDX "extended" response, adjusting various RPC handle operation access masks, uncommenting some padding code that was commented out for what appeared to be a NetWare problem, disabling some logic to use port 139 if the jcifs.netbios.hostname was set and finally adding code to include LsarQosInfo structures in the MSRPC bind.
  • +
  • Some new error code information has been added.
  • +
  • Constants for common SIDs have been added to the SID class.
  • +
  • The SID.getGroupMemberSids() method will now return an empty SID array if the SID is not of type SID_TYPE_DOM_GRP or SID_TYPE_ALIAS.
  • +
  • A minor performance flaw in the DCERPC code was found and fixed.
  • +
+

+The JCIFS Team would like to thank Simple Groupware Solutions and the Leibniz Computing Centre Munich (LRZ) for supporting this work. +

+The JCIFS Team would like to thank Vivísimo, Inc. for supporting this work. Vivísimo provides enterprises with innovative search solutions to find, access, and manipulate all content. For consumer web searches, Vivísimo offers Clusty.com. + + + + +jcifs-1.2.14 released / SID.getGroupMemberSids() and the SAMR Interface +posted by Mike, Jun 20, 2007 + +A new SID.getGroupMemberSids() method has been added that will return the local group membership of SID (aka it's aliases). The SAMR interface has been added to the dcerpc code with the SamrEnumerateAliasesInDomain RPC and numerous other calls necessary to negotiate the various handles. +

+The JCIFS Team would like to thank Vivísimo, Inc. for supporting this work. Vivísimo provides enterprises with innovative search solutions to find, access, and manipulate all content. For consumer web searches, Vivísimo offers Clusty.com. + + + + +jcifs-krb5-1.2.13 released / Kerberos Authentication Support Update +posted by Mike, Feb 8, 2007 + +The stock jcifs-1.2.13 package has been patched by a third party to support Kerberos 5 / SPNEGO extended security authentication. Additionally, SMB signing and DFS issues that existed in jcifs-krb5-1.2.9 have been fixed. +

+The JCIFS team has compiled the package and confirmed that it works with at least the one test case provided (examples/KerberosAuthExample.java) but otherwise the code should be used with caution. +

+Great thanks again to Mr. Shun from Japan for contributing this work. + + + + +jcifs-1.2.13 released / Share ACLs, DFS Fixes and NoRouteToHostException Fallback +posted by Mike, Jan 22, 2007 + +A new SmbFile.getShareSecurity() method that uses a new MsrpcShareGetInfo/ShareInfo502 RPC has been added. This will return the ACL for a share as opposed to the ACL for the directory shared. See the API documentation for details. Several DFS issues have been identified and fixed. If JCIFS receives a NoRouteToHostException on port 445 it will now try to fallback to port 139. This code has been tested fairly well already. There have been no changes since b4. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. + + + + +jcifs-1.2.12 released / NtTransQuerySecurityDesc, DFS Bugfixs and SID Adjustments +posted by Mike, Dec 27, 2006 + +The NtTransQuerySecurityDesc request could specify a data buffer that could be too small for the response. As a result the response was not decoded properly and an error would occur. The response will now be decoded properly if the buffer is too small and the buffer size has been increased from 4096 to 32768. +

+The getSecurity() method did not work over DFS. A very small but potentially significant change has been made to the DFS code. I do not have a sophisticated DFS test environment so please pay special attention to JCIFS with DFS and report any problems to the JCIFS mailing list. +

+The toString() method of the SID class has been changed back to the old behavior of returning only the numeric SID representation. This was done not only for backward compatibility with previous versions of JCIFS but because conceptually the textual representation of a SID is not it's resolved account name. A new toDisplayString method has been added to return the resolved Windows ACL editor text (as toString() did in the 1.2.11 release). The toSidString() method has been removed. The getDomainName() and getAccountName() methods have not changed. + + + + +jcifs-1.2.11 released / SID Class Adjustments +posted by Mike, Dec 9, 2006 + +The 1.2.11 release is now final. No serious problems have been reported with the new SID resolution code however some minor adjustments have been made with respect to values returned when a SID has not been resolved (e.g. the associated account was deleted). The SID class API documentation has been updated accordingly. +

+The JCIFS Team would like to thank Vivísimo, Inc. for supporting this work. Vivísimo provides enterprises with innovative search solutions to find, access, and manipulate all content. For consumer web searches, Vivísimo offers Clusty.com. + + + + +jcifs-1.2.11b released / SID Resolution +posted by Mike, Nov 30, 2006 + +This release significantly expands the SID and ACE classes by using the new MSRPC infrastructure to resolve SIDs to their associated account names. A new SmbFile.getSecurity() method has been added which if called with a boolean value of true will resolve the SIDs returned within the ACE[] array such that SID.toString()/getDomainName()/getAccountName() will return text about the account associated with that SID suitable for display to users (e.g. MYDOM\alice, SYSTEM, etc). Documentation for all associated methods and classes has been added. +

+A fix for a NullPointerException within DcerpcPipeHandle has been applied. + + + + +midlc-0.6.1 released / JCIFS MSRPC Stub Support +posted by Mike, Nov 30, 2006 + +The midlc MIDL compatible IDL compiler has been updated to emit stubs for the new JCIFS MSRPC infrastructure. For your convenience the libmba library is included and the Makefile will build a static binary (i.e. you no longer need to install libmba separately). For JCIFS MSRPC stubs use the -t jcifs option (the behavior of -t java for Jarapac remains). + + + + +jcifs-1.2.10 released / Minor Adjustments +posted by Mike, Nov 24, 2006 + +The 1.2.10 release is now final. A NetBIOS name service lookup bug has been fixed in addition to several other harmless adjustments. +

+The JCIFS Team would like to thank MetaCarta, Inc. for supporting this work. MetaCarta, Inc., a provider of geographic intelligence solutions, offers users map-driven geographic search, geographic referencing, and data visualization capabilities. + + + + +jcifs-1.2.10b released / MSRPC Support, Long Unicode Share Name Enumeration and Critical Bugfixes +posted by Mike, Nov 13, 2006 + +This release contains the following new functionality and fixes: +

    +
  • Long Unicode Share Enumeration - The SmbFile.list* methods will now try to use MSRPC to enumerate shares if the target is a server. If the operation should fail for any reason, the client will fall back to trying the older RAP method. This should permit enumerating shares with names that use charsets other than the negotiated OEM "ASCII" encoding, share names that are longer than 12 characters, and arbirarily large lists of shares.
  • +
  • MSRPC Support - MSRPC support has been integrated into JCIFS directly. It should now be possible to add new RPCs (AT jobs, SID/group name resolution, service management, regedit, etc) relatively easily with little knowledge of MSRPC protocols. Look at the jcifs/dcerpc/msrpc/MsrpcShareEnum.java class for an example and ask the mailing list for further instructions.
  • +
  • Apr 24 bugfix - A NullPointerException caused by an error in logic has been fixed.
  • +
  • May 10 bugfix - The client will now detect if the JRE supports Cp850 and set the default jcifs.encoding to US-ASCII if it does not. This will eliminate some NullPointerExceptions that were occuring as a result.
  • +
  • A small update about keep-alives has been added to the NTLM HTTP Authentication document.
  • +
  • Jun 21 bugfix - CLOSE-WAIT sockets left over by read errors have been fixed.
  • +
  • Jul 19 bugfix - Errors caused by using UnicodeLittle as opposed to UnicodeLittleUnmarked have been fixed by ensuring UnicodeLittleUnmarked is used throughout the codebase.
  • +
  • Oct 3 bugfix - Invalid state errors from Transport classes have been fixed. It should be safe to interrupt() JCIFS operations now.
  • +
  • Oct 20 bugfix - Uncontrolled looping due to invalid Transport logic has been fixed.
  • +
  • Oct 25 bugfix - Logic has been added to make domain controller lookups more robust.
  • +
  • Oct 27 bugfix - Failure when using SmbFile.renameTo() with jcifs.smb.client.ssnLimit=1 has been fixed.
  • +
  • Oct 31 bugfix - Endless looping when all WINS servers in a list are unavailable has been fixed.
  • +
+
+
+ + +jcifs-krb5-1.2.9 released / Kerberos Authentication Support +posted by Mike, Sep 13, 2006 + +This package is stock jcifs-1.2.9 modified to support Kerberos 5 / SPNEGO extended security authentication. Please note that this has no impact on the HTTP Filter which still only supports NTLM. +

+The examples/KerberosAuthExample.java is included to demonstrate using this package however note that this example initializes a logon context from a username and password. In the steady-state it is more likely that the user will already have a credential (e.g. via kinit) in which case your application code would be different. You will need to familiarize yourself with JGSS and it's Krb5LogonModule to fully utilitize this new feature. +

+WARNING: This package has been reported to work by several users however the code has not been examined carefully by jCIFS maintainers and therefore should be considered highly experimental. +

+Note: This package has been compiled with Java 1.5. It may work with eariler versions of Java but you will need to recompile and experiment to determine what the precise requirements are. +

+Great thanks to Mr. Shun from Japan for contributing this work. Ever notice Japan always get's new stuff first? + + + + +jcifs-1.2.9 released / Java 1.5 Issue, jcifs.encoding Documentation +posted by Mike, Apr 4, 2006 + +The 1.2.8 release was compiled with Java 1.5.0_06 which under certain conditions could cause the following error: java.lang.LinkageError: ... Unsupported major.minor version 49.0. I have rebuilt the entire package using the compiler I used previously (1.4.2_08). Also, the documentation regarding the jcifs.encoding property has been updated to clarify the implications of using a non-Internationalized version of the Java runtime. + + + + +jcifs-1.2.8 released / Deadlock Fix, ACLs, DFS, NTLM HTTP Filter, and More +posted by Mike, Mar 24, 2006 + +There are several significant changes in this release. These include: +

    +
  • A deadlock could occur if the client tried to logoff and logon at the same instant. This has been fixed.
  • +
  • It was discovered that in at least some cases "preauthentication" did not work properly. A very simple logical error would cause the wrong signing digest to be installed. This has been fixed.
  • +
  • The ACL patch has been integrated. The SmbFile.getSecurity() method is now available.
  • +
  • The jcifs.smb.client.responseTimeout and jcifs.smb.client.soTimeout values have been increased from 10000ms and 15000ms to 30000ms and 35000ms respectively. Users with crawler type applications will almost certainly want to reduce these values.
  • +
  • Several logical errors in DFS referral handling have been fixed (still no fix for the mystery preemtive behavior observed by Windows clients).
  • +
  • Documentation has been updated significantly.
  • +
+
+
+ + +jcifs-1.2.7 released / Transport Error, Filter Changes, Integer Overflow, User Contributed Patches, and More +posted by Mike, Nov 18, 2005 + +This release consists of the following changes. Happy Thanksgiving. +
    +
  • Some debugging printlns left over from the last release have been removed.
  • +
  • Added setContentLength(0) to two other places for the NTLM HTTP Filter. This is required for HTTP 1.0 clients (e.g. Google appliance servers).
  • +
  • The name service code will now properly resolve DNS names that begin with digits.
  • +
  • Several instances of possible integer overflow have been fixed.
  • +
  • A patch for large read and write support has been added to the patches directory. A patch for reading security descriptors has been added to the patches directory.
  • +
  • If a transport was in error due to a connection timeout it could remain in the error state indefinitely. This issue has been fixed.
  • +
+
+
+ + +jcifs-1.2.6 released / Session Management and Filter Fix +posted by Mike, Oct 7, 2005 + +It was discovered that redundant sessions could be created. This problem has been fixed but the fix is to simply not remove sessions from the list of sessions for a transport which is a waste of memory after time (although most users should not case as the number of sessions is proportional to the number of distinct credentials used). This will probably need to be revisited in the future. It has been advised that the Filter should call setStatus() before setContentLength(0). This change has been implemented. + + + + +jcifs-1.2.5 released / Filter Exceptions, Stressing the Transport Layer, and DFS Deadlock Fixed +posted by Mike, Oct 1, 2005 + +This release of the JCIFS client consists of the following changes. +
    +
  • It was discovered that a flaw in session expiration could cause sessions to expire prematurely. This has been repaired.
  • +
  • If the jcifs.netbios.hostname property is set, the client will communicate using only NetBIOS over port 139. This is required for environments that implement a policy restricting users to logging in from certain computers.
  • +
  • Under stress the client could incorrectly attempt to use the invalid "NULL" transport. This has been fixed.
  • +
  • Filter users could experience exceptions due to using the port 0 rather than the default CIFS port.
  • +
  • The client should now handle partial reads and socket exceptions more gracefully.
  • +
  • Under stress, the DFS referral query could cause the client to deadlock. This has been fixed.
  • +
+
+
+ + +jcifs-1.2.4 released / Timedout Waiting for Response Exception, Bogus Signature Error, and More +posted by Mike, Sep 21, 2005 + +A NetBIOS keep-alive message (received after ~10 minutes) would break message processesing with a timedout waiting for response Exception. This has been fixed. +

+JCIFS would fail to validate responses with a status that is not zero. Assuming we are calculating the verfication signature correctly I can only assume the affected servers choose not to generate the correct signature for error responses (perhaps for DOS reasons). Because JCIFS checked the signature before the message status, an error response would fail with "signature verification failure". This behavior has been changed so that signatures are not verified if the status is non zero. +

+It was discovered that the new transport (as of 1.2.x) could not cleanly recover from temporary server failure (e.g. a restart). This has been fixed. Methods will still throw Exceptions but the moment the server comes back online the client should gracefully recover. + + + + + +jcifs-1.2.3 released / Port 445 Fixed +posted by Mike, Aug 24, 2005 + +A mistake in the 1.2.2 release broke port 445 communication entirely. It has been fixed. The exact error (with a sufficiently high loglevel) was "Invalid payload size: 1". + + + + +jcifs-1.2.2 released / Exception "cannot assign requested address" Fixed, Clusters, NetApp Filer, and More +posted by Mike, Aug 19, 2005 + +There have been a number of small fixes. These are: +

    +
  • The "cannot assign requested address" exception caused by trying to bind the local address 127.0.0.1 has been fixed.
  • +
  • In a cluster environment the NTLM HTTP Filter could fail with "account currently disabled" or "Access denied" errors due to a deserialization issue of "preauthentication" credentials stored in the HttpSession. The initialization of default credentials has been changed however it is not clear that the change will have any effect as I do not have a clustered environment in which to test.
  • +
  • The combination of plain text passwords and Unicode (largely specific to Samba 3) has been fixed.
  • +
  • A bogus debugging statement has been discovered and removed. Who left that in there?!
  • +
  • A Socket.shutdownOutput() call has been added to doDisconnect as it is believed to reduce spurrious RST frames observed when abruptly shutting down transports. These are believed to be harmless but they have been associated with unsightly messages in Samba log files.
  • +
  • The copyTo() method will now check to see if the source path is a child, parent or equal to the destination path and if so throw a Source and destination paths overlap exception.
  • +
  • An additional debugging statement has been added to the NTLM HTTP Filter domain controller interrogation code.
  • +
  • The getDiskFreeSpace call could fail with NetApp Filer. It has been repaired.
  • +
+
+
+ + +jcifs-1.2.1 released / Signing, setAttributes, getType, and More +posted by Mike, Jul 4, 2005 + +The SMB signing code was totally broken in the last release makeing 1.2.0 useless in many environments. It has been reparied. +The setAttributes method did not work on directories. This has been fixed and the masks used to filter attributes been optimized to allow getting and setting all possible attributes based on observed XP behavior. +The getType() method would always return TYPE_SHARE if the SmbFiles were obtained through the listFiles() method. This issue has been fixed - getType() may now also return TYPE_PRINTER and TYPE_NAMEDPIPE (this has been broken for a long time BTW). There have been a variety of other subtle fixes. + + + + +jcifs-1.2.0 released / New Transport Layer, Port 445, getDiskFreeSpace +posted by Mike, May 22, 2005 + +The transport layer (the code that multiplexes requests from muliple threads over sockets) has occasionally caused trouble over the years. In general it was too complex. To remedy this problem the transport was rewritten and a forked 1.1.19 was released as the "trans" branch. This branch appears to be at stable enough that it is being released as 1.2. +

+The biggest change in this release should not be visible to users (hopefully) although some new features have managed to sneak in as a result of this merger. These new features are: +

    +
  • The client will now attempt to connect to port 445 as opposed to port 139. If this connection fails the client will fall-back to port 139.
  • +
  • If a share was disabled while jCIFS was connected an error would occur even if the share was reenabled before the client tried to access it. This has been fixed so that the client will reconnect and complete the current operation transparently.
  • +
  • The getDiskFreeSpace() method could report the wrong value for very large volumes. This has been fixed by adding a new info-level.
  • +
  • Named pipes were broken by changes for DCE/RPC transactions. They have been repaired.
  • +
  • The NetBIOS name resolution code will now use the last resource record in a name query response rather than the first. This appears to be more correct (at least with WMWare adapters on my XP workstation).
  • +
  • The client is generally faster because the transport is simpler. The amount of code for the transport is less than half of what it used to be.
  • +
+Developers writing Java network clients may want to look at the jcifs.util.transport.* classes. +
+
+ + +jcifs-1.1.11 released / File Corruption Bugfix +posted by Mike, May 4, 2005 + +If a file is opened with SmbFileOutputStream, written to, and then the client waits for jcifs.smb.client.soTimeout without any communication to the target, a subsequent write could zero the contents of the file before the current file index resulting in file corruption. This problem has been fixed. And alternative to upgrading is to use RandomAccessFile which does not have this problem. +

+Also in the download area is the "trans" release. This version has a completely rewritten transport layer, proper port 445+139 support as well as the beginnings of new features destined for 2.0. Use with caution - it's green. + + + + +jcifs-1.1.10 released / DC Lookup Rewrite +posted by Mike, Apr 17, 2005 + +The code used by the NTLM HTTP Filter to lookup and rotate through domain controllers has been considerably simplified. The NtlmChallenge class is now Serializeable, the timeout for rebuilding the filters DC list has been increased from 20 minutes to 10 hours, and the jcifs.netbios.lookupRespLimit default has been reduced to 3. + + + + +jcifs-1.1.9 released / Read Error +posted by Mike, Feb 28, 2005 + +When multiplexing I/O, if socket buffers fill up such that packets can be read in fragments (i.e. high load), it was possible for the 4 byte NetBIOS header to be read incorrectly resulting in a bogus unexpected EOF reading netbios session header exception. This problem has been fixed. Also, some small javadoc updates have been applied. + + + + +jcifs-1.1.8 released / Blocked Threads Again, DC Lookups, Name Service, and More +posted by Mike, Feb 11, 2005 + +The blocked thread bug wasn't quite fixed in the last release. A lookup exception (e.g. caused by an unresponsive domain controller) could leave a thread blocked if many requests are being processed simultaneously. Similarly the fix for the DC lookup code wasn't complete enough to handle the unusual scenario where all DCs are unresponsive. Also, a malfomed NetBIOS name query response could cause the name service thread to exit incorrectly. These issues have been fixed. Finally, the URL handling of smb://@/ (meaning "null" credentials) has been fixed. + + + + +jcifs-1.1.7 released / Blocked Threads, DC Lookups, Signatures, and Other Fixes +posted by Mike, Jan 16, 2005 + +A bug introduced in a recent release that could cause threads to wait indefinately has been fixed. After time many threads could be blocked resulting in wasted resources. The DC lookup code has been modified to gracefully handle WINS returning an empty list (e.g. due to temporary network failure). A simple fix has been applied that premits SMB signatures to work without specifying preauthentication credentials. The getAttributes() method will now return 31 bits of attributes whereas previously it would mask the lower 6 bits that JCIFS actually uses. A bug has been fixed that under certain conditions prevented copyTo() from copying entire shares. A try/catch block has been added to copyTo() to permit the copy to continue if an error occurs. + + + + +jcifs-1.1.6 released / Minor Adjustments +posted by Mike, Dec 27, 2004 + +If a variable length 8 bit encoding such as Big5 was used the NTCreateAndX command could fail. This bug has been fixed. If an SmbFile{Input,Output}Stream was closed, a subsequent operation could cause the file to be reopened. This behavior is now blocked such that operations performed on a stream after it has been closed will generate an IOException (to conform to java.io streams behavior). Some transport layer synchronization has been adjusted. A getPrincipal method has been added to SmbFile that will return the NtlmPasswordAuthentication object used as credentials for the file or pipe. An adjustment has been made to the NbtAddress.firstCalledName method that streamlines communication with domain controllers. The documentation has been updated regarding transparent NTLM authentication in Mozilla and the available() method of SmbFileInputStream. + + + + +jcifs-1.1.5 released / ArrayIndexOutOfBoundsException +posted by Santa, Dec 17, 2004 + +It was discovered that an ArrayIndexOutOfBoundsException could occur if the list of domain controllers returned by NbtAddress.getAllByName was shorter than the list returned in the previous call (possibly because the WINS query timed out and switched to an alternate WINS server). All NTLM HTTP Authentication Filter users should upgrade to prevent this error. Also, the value of jcifs.netbios.cachePolicy set by the NTLM HTTP Filter if it is not specified has been doubled to 20 minutes. Finally, some log levels have been increased such that running with jcifs.util.loglevel = 3 temporarily is actually reasonable in a production environment (must use loglevel > 3 to see individual SMB messages and loglevel > 5 to get hexdumps). + + + + +jcifs-1.1.4 released / LMv2 Fix +posted by Mike, Dec 7, 2004 + +Two bugs regarding the upcasing of domain and username fields with LMv2 authentication (used with lmCompatibility = 3) have been fixed. Additionally the firstCalledName/nextCalledName methods changed in 1.1.0 have been changed back to the old behavior. The change was not warranted as it did not emulate Windows behavior. + + + + +jcifs-1.1.3 released / Concurrency Error Fixed +posted by Mike, Nov 30, 2004 + +A concurrency error that was introduced with the getChallengeForDomain() code used by the NTLM HTTP Filter has been repaired. + + + + +jcifs-1.1.2 released / Bogus Debugging Statement +posted by Mike, Nov 2, 2004 + +Opps! A harmless println statement that found it's way into the last release has been removed. + + + + +jcifs-1.1.1 released / logonShare and DCE Pipe Fixes +posted by Casper, Oct 31, 2004 + +The jcifs.smb.client.logonShare (and thus the JCIFSACL NTLM HTTP Filter example) did not work. It would not restrict users to those found in the ACL and would instead permit all authenticated users. This has been fixed. A bug was discovered and fixed in the named pipe code. If a specific sequence of reads were performed the pipe could become corrupted. This fix is necessary for multi-pdu DCE requests to work. A small bug in the new NbtAddress.getAllByName() method has been repaired. It will now broadcast for a name if a WINS address was not provided. + + + + +jcifs-1.1.0 released / NTLM HTTP Authentication Improvements +posted by Mike, Oct 1, 2004 + +There have been significant changes that should improve the reliability and overall behavior of JCIFS particularly for users of the NtlmHttpFilter. +

    +
  • NbtAddress.getAllByName - The NbtAddress.getAllByName() method has been implemented that will return all RDATA records for a NetBIOS name. Thus, you can now retrieve the full list of domain controllers with NbtAddress.getByName( "MYDOM", 0x1C, null, null ). The old behavior of returning a random entry from the getByName method has been eliminated.
  • +
  • SYN Timeout - The socket code has been modified to employ the transport thread when opening a new connection. This eliminates the annoying 1min+ hang that occurs trying to connect to a non-existant but routable addresss (i.e. the single threaded SmbCrawler example is relatively fast now).
  • +
  • SmbSession.getChallengeForDomain - A new method has been added to retrieve an object that encapsulates both the server session key (a.k.a. challenge) and the UniAddress from which it came. This method is used solely by the NTLM HTTP Authentication Filter to eliminate the possibility for a different domain controller to be queried in the middle of client nogotiation. Prior to this release this could result in temporary authentication failures. This code uses the new getAllByName method to build a list of domain controllers suitable for authenticating web clients. The clent will rotate evenly through the list and remove entries that are unresponsive. This makes the filter very resilent to domain controller failures.
  • +
  • Session Expiration - because of the above changes the client will now proactively close idle sessions. This is particularly pertainent to the NTLM HTTP Filter which really only touches the session when it is first created as the resulting credentials are cached in the user's HTTP session.
  • +
  • Read Bug - A read bug in JCIFS that affected EMC Celera servers has been fixed.
  • +
  • NetBIOS CalledName - The firstCalledName/nextCalledName methods have been modified to try SMBSERVER* first and fall back to other names. This should eliminate a round trip during session establishment in newer environments.
  • +
+Finally, I have updated the sample web.xml. It should be used as a stationary in all production environments. +
+
+ + +jcifs-1.0.1 released / Guest Account Broken +posted by Mike, Sep 6, 2004 + +The guest account fix released 6 hours ago broke guest access entirely. The original fix has been re-applied but with the bad test condition corrected. + + + + +jcifs-1.0.0 released / 5 Years and Beyond +posted by Mike, Sep 6, 2004 + +According to the freshmeat page, JCIFS is 5 years old today (vote for us!). The project has come a long way in those years. Its features now include: +
    +
  • +The NTLM HTTP Authentication Filter, which adds easy Single Sign On (SSO) functionality to Java Servlet containers, is clearly the most popular feature of JCIFS. Eric did a great job of deciphering the details of that protocol. The filter is mind-numbingly easy to install as all it requires is the JCIFS jar and a filter section in your web.xml with two or three init parameters [1]. +
  • +The performance of JCIFS is one of its more surprising achievements. Consider the client can enumerate 5GB of files and directories in less than 10 seconds [2]. To reduce memory usage and increase concurrency JCIFS automatically reuses existing transports and sessions. One nice artifact of this design is that the NTLM HTTP Authentication Filter scales to thousands of active clients. And because the negotiated credentials are cached in the user's HTTP session the number of concurrent user's supported can be many times greater than that. +
  • +The SmbFile.copyTo() method is a venerable feature in itself. All file and directory attributes and timestamps are mirrored perfectly [3]. It employs an extra thread to write data while the next read operation is in progress. This optimization makes JCIFS the fastest client available for copying large trees of files and directories across hosts (neither of which needs to be the local machine). +
  • +Accessing DFS volumes (sub-trees of files and directories that actually reside on another host) is fully transparent to the user. The client may be redirected multiple times in the middle of any operation. After a redirection has occurred the mapping is cached but the cache is only queried for transports that indicate they host DFS volumes. +
  • +SMB signing is robust and negotiated automatically with servers that require it. +
  • +The SmbRandomAccessFile implementation is a complete drop in replacement for the standard java.io.RandomAccessFile. When opened with SmbFile.FILE_NO_SHARE share access this class is a legitimate database API. +
  • +Named Pipes of all types are fully supported. TransactNamedPipe, CallNamedPipe, and standard file I/O style pipes are all supported using a single generic API that conforms to the InputStream/OutputStream model. +
  • +JCIFS' name resolution capability is very sophisticated. WINS, DNS, NetBIOS broadcast queries, and remote lmhosts files are supported well. Which services and the order in which each service is queried is fully configurable. The name service cache policy is also adjustable. +
  • +JCIFS implements the SMB URL Draft Specification V07 and processes all SMB URLs through an SMB URL proticol handler. This same handler is used to build standard java.net.URL objects which means once the protocol handler is registered SMB URLs can be used with any application that uses URLs (e.g. -Djava.rmi.server.codebase=smb://mymachine/c/download/myapp.jar). +
  • +
+Other features include NTLM and LMv2 Authentication [4], optimal request batching, NT STATUS codes, full transactions, large file support, Unicode support from the ground up [5], NTLM HTTP authentication wrappers for HTTP and HTTPS clients, a simple logging facility, and extensive documentation. If that's not enough, there's always jcifs-ext where bleeding edge JCIFS extensions live. +

+But the best feature of JCIFS is the simplicity of the API itself. We have diligently resisted "feature creep". The SMB URL allows addressing resources with wonderful ease. The SmbFile class is a drop in replacement for java.io.File so if you know how to use that, you know how to use JCIFS. +

+JCIFS is now one of the most sophisticated and powerful CIFS clients available free or otherwise. It is used in production environments by many large commercial organizations and the Open Source model has worked well for us as these users have contibuted valuable feekback that has made JCIFS rock solid. +

+To commemorate these achievements we are proud to release JCIFS 1.0. Aside from fixing broken links and a few packaging tweaks it is not different from 0.9.8 and we hope it stays that way. Moving forward, the 1.0 branch will only receive critical fixes. +

+In recent weeks a MIDL compatible IDL compiler was developed. Coupled with the Jarapac DCE/RPC framework for Java it is now practical to make MSRPC calls. This means that the Microsoft network management API functions are very close to being incorporated into JCIFS. IDL files need to be written and APIs need to be devised but we will soon be able to create users, edit groups, control NT services, reboot machines, edit the registry, execute programs on a remote host, and much much more. This will open up an entirely new level of integration between Java and Microsoft environments. +

+Finally, thanks goes out to Eric and Chris and everyone else that has contributed their time. JCIFS is truely a great product because we have taken full advantage of the Open Source model. We would not have made nearly as much progress without the code, bug fixes, problem reports, and solutions provided by our users. +

+ +[1] although running through web servers that also try to negotiate NTLM HTTP or do not properly support keep-alives is problematic
+[2] Client Host: 500MHz Debian Linux "testing" Java 1.4 JCIFS 1.0.0; Target Workstation: 2.7GHz 5.77GB Windows NT 4 sp6; Nework: 100 Mbps full-duplex switched; Test Program: examples/T2Crawler.java with println statements commented out, default properties, ran 3 times to load up target workstation cache; Results: $ time java -Djcifs.properties=../miallen.prp T2Crawler smb://myworksta/c$/ 3 1000, real 0m9.929s user 0m5.580s sys 0m0.600s
+[3] although currently extended attributes are not copied
+[4] NTLMv2 is not fully supported but LMv2 permits the client to operate in NTLMv2 environments
+[5] Unicode share names are not supported but will be soon now that RPCs are underway
+
+ + + + +jcifs-0.9.8 released / Guest Account Again and Minor Adjustments +posted by Mike, Sep 3, 2004 + +If the "guest" account on a server was not disabled as it normally is it would be possible for a user to use an invalid username to access an SMB resource or website protected with the NtlmHttpFilter. JCIFS will no longer successfully authenticate the "guest" account at all (even if the guest account is enabled and the user enters "guest"). A log message will now be generated for all SmbAuthExceptions in the NtlmHttpFilter if the jcifs.util.loglevel property is set to 2 or greater. Behavior regarding accessing System properties has been curbed to accomodate more restrictive environments. Finally a benign exception that could occur if the client was misconfigured has been fixed. + + + + +jarapac-0.3.4 and idlc-0.3.6 released / DCE RPC Working +posted by Mike, Aug 28, 2004 + +After several weeks of hard work on our MIDL compatible IDL compiler, MS-RPC calls are now working with the Jarapac DCE framework. Currently only the ncacn_np transport in Jarapac works but other transports (e.g. TCP port 135) should work without too much trouble. The process is very easy now -- write IDL, compile with idlc, write Jarapac driver program, and go. The Jarapac examples directory has the beginnings of lsarpc, samr, and srvsvc interfaces. This should unlock a whole new set of functionality for integrating Java into Windows networks. Eat your heart out Microsoft! + + + + +jcifs-0.9.7 released / Minor Adjustments +posted by Mike, Aug 11, 2004 + +The NTLM HTTP Filter will no longer set Connection: close, a new SmbFile constructor has been added and a rogue debugging statement has been removed. + + + + +jcifs-0.9.6 released / copyTo Bug and Many Other Fixes +posted by Mike, Jul 23, 2004 + +A bug in copyTo() has been found and fixed that could result in the operation failing and timing out. The default jcifs.smb.client.snd_buf_size has been changed from 5000 to 16644. When copying data between larger servers with copyTo() (servers that negotiate larger buffer sizes) the result is a noticable preformance increase. Adjustments have been made regarding a null pointer exception triggered by an internal method during certain error scenarios. The client will now failover to a jcifs.smb.client.domain controller for browser information if the LMB query fails. Methods have been added to SmbSession that support the specification of alternative port. Some incorrect debugging output has been fixed. A clause has been added to SmbFile.delete() to subvert an exception caused exclusively by the Oracle FilesOnline CIFS implementation. The NTLM HTTP Authentication documentation has been slightly updated. + + + + +SMB URL IETF Draft Version 7 +posted by Chris, Jul 8, 2004 + +The latest SMB URL Draft has been posted. JCIFS tries to conform to this SMB URL specification as closely as possible. + + + + +jcifs-0.9.5 released / Workgroup Server Enum Fix and updated NtlmHttpURLConnection +posted by Mike, Jul 2, 2004 + +A bug introduced in 0.9.3 could result in an infinite loop that exhausts all memory in the VM when enumerating workgroups and servers. This issue has been fixed. Also included is an updated to the NtlmHttpURLConnection (now works with org.apache.xmlrpc.XmlRpcClient). + + + + +JCIFS Extensions for SPNEGO Filter and RAP Functions +posted by Eric, Jul 1, 2004 + +A project for jCIFS extensions called jcifs-ext has been established on Sourceforge. Currently this project hosts the latest versions of the SPNEGO HTTP Filter and the RAP function library. + + + + +jcifs-0.9.4 released / Credential Propagation and NTLM for HTTP Clients +posted by Mike, Jun 30, 2004 + +Credentials were not being propogated to files returned by listFiles() or to parent files used in mkdirs(). This could result in inappropriate authentication exceptions. Also NTLM HTTP support for HTTP clients (NtlmHttpURLConnection) has been updated to support NTLM negotiation using the POST method. + + + + +jcifs-0.9.3 released / The SMB URL Port Field and Full Enumeration of Workgroups and Servers +posted by Mike, Jun 29, 2004 + +A bug has been fixed that will now permit jCIFS to enumerate all workgroups and servers. Also included is a fix for the SMB URL port field that was previously being ignored. + + + + +Davenport 0.9.9 released +posted by Eric, Jun 29, 2004 + +This release includes some session serialization fixes as well as other minor items noted during testing. + + + + +Davenport 0.9.9b released +posted by Eric, Jun 18, 2004 + +The latest version of Davenport adds support for URL rewriting based on a context base, per-server authentication caching, disabling closing of HTTP connections upon request for authentication, support for pluggable error handlers and logging, the ability to specify anonymous credentials, and a file filter framework. The jCIFS library bundled with Davenport has also been updated to 0.9.2. + + + + +jcifs-0.9.2 released / Deadlock in copyTo +posted by Mike, Jun 8, 2004 + +An initialization race in the SmbFile.copyTo() method has been discovered and fixed. Also the documentation work continues. + + + + +jcifs-0.9.1 released / Security Update +posted by Mike, Jun 1, 2004 + +If the "guest" account is enabled on a CIFS server it is possible for jCIFS to successfully authenticate even with an invalid username. Windows networks virtually always disable this account but apparently it is not difficult to enable this condition when using Samba. NTLM HTTP Filter users that are not certain the "guest" account is disabled should upgrade. This release eliminates the possability of authenticating anyone without a valid username. Specifically, a small clause has been added that throws an SmbAuthException if the server responds with the "is logged in as guest" bit on. + + + + +jcifs-0.9.0 released / Documentation +posted by Mike, May 28, 2004 + +There have been no reports of problems so the aside from a very minor adjustment to the code all changes in this release are to the documentation. In particular the NTLM HTTP Authentication documentation has been significantly improved. The API documentation still needs work but it is believed to be accurate. + + + + +jcifs-0.9.0b released / General Cleanup and Minor Enhancements +posted by Mike, May 14, 2004 + +And thus begins the 0.9 series. This should solidify fairly quickly although there have been some pervasive changes. The details are as follows: +

    +
  • PropertiesTree has been removed. Thus properties must now be specified using the full name only.
  • +
  • Multiple WINS servers may now be specified using a comma separated list of IPs (i.e. jcifs.netbios.wins=192.168.2.10,172.21.1.1,10.44.55.66).
  • +
  • The NtlmHttpFilter has been modified to support "preauthentication" such that if the jcifs.smb.client.{domain,username,password} properties are supplied as init parameters, all transports will be initialized with these credentials. This is the ideal setup for domain controllers that require SMB signatures (although it has been observed that NT 4.0 at least does not check the signatures of authentication requests).
  • +
  • NT status codes are now used in favor or DOS error codes even if DOS error codes are negotiated (mapped to NT status codes immediately after being decoded). You can lookup NT status codes here. The package used to generate this file and the jCIFS code tables is in the download area.
  • +
  • The NetServerEnum3 operation has been added (thanks Gary) such that large lists of workgroups and servers may now be enumerated (doesn't help with large numbers of shares).
  • +
  • Fixed some incorrect path handling in the DFS referral code.
  • +
  • It is now NOT possible for a session setup to be transmitted if the NtlmPasswordAuthentication object's hashes were created with a server challenge that does not match the current encryptionKey of the transport. If this condition occurs and SmbAuthException with an NT status of NT_STATUS_ACCESS_VIOLATION will be thrown. The NTLM HTTP Filter and NetworkExplorer servlet have both been modified to catch this exception and issue an HTTP redirect to the original URL to reinitiate the NTLM negotiation.
  • +
  • The jcifs.smb.client.ssnLimit property will now open redundant transports if the limit is reached. The old behavior of closing 10% of the oldest sessions has been eliminated.
  • +
  • Several SMB signing fixes. The SMB signature code has been mostly moved into the SigningDigest class.
  • +
  • Additional checks in the initial connection code have been added to reduce/eliminate lingering CLOSE_WAIT sockets.
  • +
  • If PIPE_TYPE_TRANSACT and PIPE_TYPE_CALL are not specified a TRANS_WAIT_NAMED_PIPE will be issued before the open call to emulate WaitNamedPipe followed by CreateFile behavior.
  • +
  • All access specifiers have been reviewed and changed to private, static, final, etc wherever appropriate.
  • +
  • The queue used to manage MIDs has been removed in favor of something considerably simplier. Performance should be improved.
  • +
  • The NetBIOS socket OutputStream has been simplified to remove a potential copy of data. Performance should be improved.
  • +
  • The NBT header length is now checked after decoding an SMB to detect and skip incorrect byte counts. This should bypass the OS/400 bug reported.
  • +
  • Property defaults for jcifs.smb.client.listCount and jcifs.smb.client.listSize have changed from 15 to 200 and from 1200 to 65535 repspectively. High latency networks should set these values back to the old values.
  • +
+Bare in mind the documentation has not been updated. That's next. +
+
+ + +jcifs-0.8.3 released / Write Corruption with HotSpot VM on Linux +posted by Mike, Apr 20, 2004 + +A bug in Sun's HotSpot VM can cause jCIFS to incorrectly encode file offsets in write requests resulting in massive file corruption. Once the error occurs it cannot be stopped without restarting the VM. If you are using the java -server option on Linux with a long lived multithreaded application that uses jCIFS to write files it is strongly recommended that you upgrade to 0.8.3. This release eliminates some redundent code that was ultimately triggering the bug in the HotSpot VM. +

+Big thanks to Richard Heap for diagnosing and fixing this very elusive problem. + + + + +jcifs-0.8.2 released / DST and getParent Fixes +posted by Mike, Mar 15, 2004 + +The daylight savings time adjustement does not appear to work correctly. Commenting out the adjustment appears to exibit the desired behavior but the issue may need further tuning. The problem regarding SmbFile.getParent() returning unexpected results has been fixed. + + + + +jcifs-0.8.1 released / Listing Adjustments +posted by Mike, Feb 26, 2004 + +All list methods will now return ATTR_HIDDEN files unless specifically filtered. It was decided that hiding hidden files is the job of a UI and not the API. Several bugs have also been fixed regarding attribute caching, the createNewFile method and setLastModified invalidating the create time. + + + + +Davenport 0.9.8 relesed +posted by Eric, Feb 13, 2004 + +A bug introduced in 0.9.7 (observed against Windows 2000 and Gnome Nautilus clients) has been fixed. + + + + +Davenport 0.9.7 relesed +posted by Eric, Feb 12, 2004 + +A bug involving redirects for directories not ending in "/" as well as various bugs involving incorrect WebDAV properties have been fixed. Additional localization support has been added. + + + + +jcifs-0.8.0 released +posted by Mike, Feb 11, 2004 + +The 0.8 beta cycle is now over. There is no technical difference between this release and 0.8.0b1. + + + + +Davenport 0.9.6 released +posted by Eric, Feb 9, 2004 + +This release provides minor bugfixes and enhancements; most notably, configuration options have been established to allow interoperability with Windows 2003 servers in the presence of SMB signing. See the Davenport project page for details. + + + + +jcifs-rap-0.8.0b1 released / Remote Administration Protocol (RAP) Branch +posted by Mike, Feb 6, 2004 + +Eric has created a modified version of jCIFS that supports the following RAP functions: +

    +
  • NetGroupAdd -- Creates a global (domain) group on a DC
  • +
  • NetGroupDel -- Deletes a global group on a DC
  • +
  • NetGroupAddUser -- Adds a user to a global group on a DC
  • +
  • NetGroupDelUser -- Removes a user from a global group on a DC
  • +
  • NetGroupEnum -- Enumerates the global groups on a DC
  • +
  • NetGroupGetUsers -- Enumerates the members of a global group on a DC
  • +
+
    +
  • NetServerEnum -- Enumerates servers in a domain/workgroup (reimplementation)
  • +
  • NetServerGetInfo -- Gets server information
  • +
+
    +
  • NetShareAdd -- Adds a share to a server
  • +
  • NetShareDel -- Removes a share from a server
  • +
  • NetShareEnum -- Enumerates the shares on a server (reimplementation)
  • +
+
    +
  • NetUserAdd -- Creates a domain or machine-local user
  • +
  • NetUserDel -- Deletes a domain or machine-local user
  • +
  • NetUserEnum -- Enumerates the users on a domain or machine
  • +
  • NetUserGetGroups -- Enumerates the global groups to which a user belongs
  • +
  • SamOemChangePassword -- Changes a user's password
  • +
+He claims: +

+"There are also GroupUtilities, ServerUtilities, ShareUtilities, and +UserUtilities classes which provide simplified versions of the primary +functionality. +

+Most of the group-related stuff needs to be run against a DC, as it only +works with global domain groups rather than machine local; that requires +RPC, from what I gather. None of this has been tested extensively, so +results may vary. But I figured you might like to play with it; it's +fairly interesting stuff." + + + + +jcifs-0.8.0b1 released / DFS with NetworkExplorer +posted by Mike, Feb 3, 2004 + +Some work has gone into getting DFS to work with NetworkExplorer +and all fixes from the 0.7 series since 0.7.15 have been incorporated. +Otherwise, the 0.8.0 series seems quite stable so far. + + + + +jcifs-0.7.19 released / SMB Signing Fixes +posted by Mike, Jan 19, 2004 + +SMB signature varification was not working properly. There have been several fixes but one problem remains. If there is a quick succession of reads and writes with the same host (i.e. copying a file) signing can fail. The source of the problem has not yet been identified. + + + + +jcifs-0.7.18 released / NTLM HTTP Filter Fixes +posted by Mike, Jan 7, 2004 + +The NTLM HTTP Authentication Filter should now work with domain controllers +that negotiate signing without generating the benign "exception +reading from socket input" error. Also, the NtlmPasswordAuthentication +class is now Serializable to increase compatability with certain Servlet +containers. + + + + +jcifs-0.7.17 released / "exception reading from socket input" Exception No More +posted by Mike, Dec 23, 2003 + +JCIFS will now suppress the harmess "exception reading from socket input" +message being written to the log. + + + + +jcifs-0.7.16 released / NetWare 6 Fix +posted by Mike, Dec 9, 2003 + +An issue regarding writing to NetWare 6 servers has been resolved. + + + + +jcifs-0.8.0b released / Lots of New Features +posted by Mike, Nov 24, 2003 + +This is the first beta release of the 0.8 series. There have been +significant additions to this package. The most noteable is Distributed +FileSystem (DFS) support. This client fully supports DFS with deep paths, +multiple redirects, you name it. This functionality required pervasive +changes so DFS users should proceed with caution and report any problems to +the mailing list. Support for setting file attributes has been added as is +the long awaited RandomAccessFile. +

+Here is a more specific breakdown: +

    +
  • DFS - DFS support is thorough. All DFS operations are completely +transparent. It Just Works. The client can be redirected an infinate +number of times. It will reuse mappings established by other callers. +Components of a path that do not fall within the DFS space and deep paths +are handled properly. Also, note the new getDfsPath method can +be used to determine if a file or directory falls within a DFS space. +This support required pervasive changes so proceed with caution and run +your unit tests with files that span DFS volumes. Please report any +problems to the jCIFS mailing list. +
  • +
  • Random Access Files - The SmbRandomAccessFile class has been +added. All features of the analygous java.io.RandomAccessFile +class are supported and should function as a drop in replacement. Notice +it is now possible to set the size of a file with the +SmbRandomAccessFile.setLength() method. Also check out +SmbTableFile.java in the examples directory for a nifty +persistant storage class. When used with SmbFile.FILE_NO_SHARE +this might serve as a reasonable poor man's database. +
  • +
  • File Filters - Support for SmbFilenameFilter and +SmbFileFilter is complete. Because CIFS servers can accept +attributes and a wildcard expression for filtering entries on the server +side, a DosFileFilter is provided that will accept these +parameters and pass them to the server. The DosFileFilter can +also be extended to create highly sophisticated and efficient file +filters. Because of this work the list() and listFiles +methods have been refactored and actually reduced in size. +
  • +
  • Complete copyTo - The SmbFile.copyTo operation will now copy all +file attributes as well as create and last write times. Directories +copied using this method should be indistinquishable from the original +minus ACLs. This method can now copy entire shares whereas previously +only sud-directories could be specified. +
  • +
  • Setting Attributes and Times - It is now possible to set file attribites, +the create time, and last write time in a variety of ways. The new +methods are setCreateTime, setLastModified, +getAttributes, setAttributes, setReadOnly, and +setReadWrite. +
  • +
  • Complete Delete - The SmbFile.delete() method will now +completely delete directories regardless of wheather or not there are +read-only files in them. +
  • +
  • The createNewFile Method - An SmbFile.createFile method has been +added. +
  • +
+
+
+ + +jcifs-0.7.15 released / Load Balancing Across Domain Controllers +posted by Mike, Oct 23, 2003 + +The name service code has been modified to return a different response with +each 0x1C domain controller query. The range of servers is limited to the +top jcifs.netbios.lookupRespLimit entries in the NetBIOS response. The +effect that this will have is that the NtlmHttpFilter and NtlmServlet will +rotate through domain controllers when authenticating WWW clients. Also, +because different transports are used, fewer sessions will be multiplexed +over each resulting in an increase in scalability proportional to the +number of domain controllers used. This behavior can be turned off by +setting the jcifs.http.loadBalance property to false (the default is true). +

+The jcifs.smb.client.ssnLimit property default value has been changed to +250 from 100. + + + + + +jcifs-0.7.14 released / Fixes +posted by Mike, Oct 6, 2003 + +An from Eric that improves (corrects) LMv2 support has been merged. There is some uncertainty surrounding +the signing of SMBs if guest credentials are negotiated. +A minor syncronization issue has been recified. +Finally there has been +a straight forward but potentially dangerous change in SmbFile. All list +operations now build a list of names or files using an ArrayList. This +assisted in fixing another problem where NetServerEnum2 responses were +observed to return server names of 0 length which caused +ArrayIndexOutOfBounds exceptions. These entries are now ignored. + + + + + +jcifs-0.7.13 released / SMB Signing Support +posted by Mike, Sep 17, 2003 + +JCIFS now supports SMB signing. If a server requires SMB signing (Windows +2003 requires it by default) or if the server supports signing and the +jcifs.smb.client.signingPreferred property is true signing will be +negotiated and used. Signing does not work with NTLM HTTP authentication +because the original password hashes are required to generate the MAC +signing key. There have also been some adjustments to SmbFile.hashCode(). +Previously jCIFS did not precisely exhibit the behavior described in the +comments for hashCode() and equals(). + + + + + +jcifs-0.7.12 released / ERRSVR/90 Fix +posted by Mike, Sep 1, 2003 + +CIFS permits multiple users to be logged in over the same transport +(socket). JCIFS takes advantage of this and reuses existing transports +wherever possible. It was reported that a user using the NTLM Servlet +Filter was getting ERRSRV/90 which means "Too many Uids active on this +session". So it looks like the limit is ~150 sessions per transport. I have +added code to logoff 1/10th of the sessions if the +jcifs.smb.client.ssnLimit propery is exceeded (default 100). update: this value was later reported to be low and has been increased to 250. + + + + +jcifs-0.7.11 released / LMv2 Authentication Support +posted by Mike, Jul 10, 2003 + +Support for LMv2 authentication has been added. See the Overview page in +the API documentation regarding the jcifs.smb.lmCompatibility property. +Some additonal "cleanup" has also been performed. One side-effect that +might be noticed is that the default domain/username/password can no longer +be set at runtime. Once the client is initialized the default credentials +are fixed. Setting default credentials are runtime was always an unsafe +operation. Create an NtlmPasswordAuthentication object instead. + + + + +jcifs-0.7.10 released / NTLM Protocol Documentation +posted by Mike, Jul 3, 2003 + +There have been two small bug fixes in the SMB layer; the count field in +the SMB_COM_WRITE_ANDX response was being ignored. Apparently the count +specified in the request is always honored or we would have seen plenty of +file corruption by now. Second, the list() and listFiles() did not properly +handle Transaction buffering with certain values for the listSize and +listCount properties (if multipart transaction responses are send). Also +removed a few obnoxious warnings getting logged during file transfers if +Log.WARNINGS is set. +

+Regarding NTLM HTTP Authentication; there have been additions and updates +to the documentation on the NTLM flags, a fix to NtlmSsp to only provide +the target when requested by the client via the NTLM "request target" flag +(this is the correct behavior), and a bugfix to NtlmSsp regarding +Base64.encodeBytes +Eric has prepared excellent +documentation detailing his analysis of the NTLM protocol: +

+http://davenport.sourceforge.net/ntlm.html + + + + +jcifs-0.7.9 released / Important Fix +posted by Mike, Jun 12, 2003 + +It was discovered that if a server responds to the NBT session setup but +not to the SMB_COM_NEGOTIATE request the client will hang indefinately. +This is not a likely thing to occur because servers usually respond or not +at all. Regardless it has been fixed. The client will timeout after +jcifs.netbios.soTimeout in this situation. +

+Some tweeking of the NTLM http code has been performed. + + + + +jcifs-0.7.8 released +posted by Mike, May 28, 2003 + +A bug in the new ntlm http client code was identified and fixed. + + + + +jcifs-0.7.7 released +posted by Mike, May 27, 2003 + +A deadlock was identified in SmbTransport.java very similar to the last one found +about a year ago. A simple but significant change has been made that greatly simplifies +synchronization in the transport layer. It eliminates this issue as well as +the extra synchronization introduced to fix the previous problem. It is an +elemental change however so proceed with caution (Update Jun 1: Reports are good; no problems). +

+Two new packages have been introduced. The jcifs.ntlmssp package now +contains some NTLMSSP base classes. This code is used by the NtlmHttpFilter as +well as the new NtlmHttpURLConnection class for transparently enabling +your HTTP and HTTPS client to negotiate NTLM authentication with IIS, the jCIFS Filter, Sqiud proxy, etc. +The other new +package is jcifs.https which just contains the HTTPS protocol handler +necesary for proper protocol handler registration. +Please read the document entitled Using JCIFS NTLM Authentication for HTTP Connections for important information about this new functionality. +

+Some open flags internal to SmbFileOutputStream have been changed to permit unusual named pipe modes to be used that previously were not considered. +

+Previously it was possible for jCIFS to report incorrect (old) +file size and modification time values after writing to the file. The attribute expiration period is now reset in SmbFileOutputStream.write() to prevent this problem. It is also possible to work around the problem by setting jcifs.smb.client.attrExpirationPeriod = 0 although doing so may impact performace. +

+Previously using the SmbFileInputStream.skip() method meant data would be read and then discarded. +This implementation of this method has been changed so that data is not read; there will be no IO to the server. +This might be useful to applications that wish to resume a large download from a certain offset within a file in the event of a network failure. + + + + +jcifs-0.7.6 released +posted by Mike, Apr 16, 2003 + +The SmbFile.isDirectory() method has been changed to return false if the target does +not exist. Previously this would return true which is inconsistent with +java.io.File. + + + + + +jcifs-0.7.5 released +posted by Mike, Apr 2, 2003 + +More refinement to the NTLM HTTP authentication code has been applied. +There is also a fix for listing hosts from Windows ME/98/95 local master +browsers. + + + + +jcifs-0.7.4 released +posted by Mike, Mar 26, 2003 + +Some NtlmHttpFilter issues were reported by several users with Windows 98 clients. +Eric has provided a new NtlmSsp.java that permits the Filter to work correctly with these +clients. + + + + +jcifs-0.7.3 released +posted by Mike, Feb 12, 2003 + +Under certain conditions the SmbSession.logon() method could +accept an incorrect password because of how SmbSession +objects are shared internally. This mehtod will now always +throw a SmbAuthException if incorrect credentials are +supplied. A minor change has also been made to the behavior of the +NtlmHttpFilter and NetworkExplorer servlet that +provokes the Network Password dialog to be redisplayed repeatedly +until correct credentials are entered by the user. + + + + +jcifs-0.7.2 released +posted by Mike, Feb 5, 2003 + +A serious bug was found that causes an +ArrayIndexOutOfBoundsException to be thrown if the len +parameter of SmbFileOutputStream.write() is 1501, 1502, or +1503. Also, the FILE_SHARE_READ, FILE_SHARE_WRITE, +FILE_SHARE_DELETE, and FILE_NO_SHARE constants have +been exposed in SmbFile to specify a shareAccess +parameter to SmbFileOutputStream and SmbFile to +restrict other processes from accessing files opened by jCIFS. The +SmbFileOutputStream now supports offsets greater than 4GB. + + + + +jcifs-0.7.1 released +posted by Mike, Jan 16, 2003 + +Three bugs have been fixed, regarding filenames with '#' signs in them, the getInputStream(), getLastModified(), getDate(), and getContentLength() methods of the URLConnection implementation, and isExists() incorrectly returning false. + + + + +Updated SMB URL Internet Draft +posted by Chris, Jan 15, 2003 + +Revision 04 of the SMB +URL draft specification is now available. + + + + +jcifs-0.7.0 released +posted by Mike, Jan 8, 2003 + + + +This release of the jCIFS client includes new functionality specifically targeting Web applications +as well as some critical SMB URL fixes and feature improvements. They are outlined in greater detail below. Enjoy! + +

    +
  • The new jcifs.http package is very handy when building +Web applications that need to integrate with MS corporate intranets. Adding +a hyperlink to a document on a network drive is easy with Network +Explorer (pictured right) and will transparently negotiate credentials +with MSIE to browse SMB resources (really, no password dialog necessary). This package also boasts an NTLM HTTP Authentication servlet Filter +for authenticating MSIE clients. These are useful features because many of +the tasks surrounding user management now fall back to computer support +and HR. It is not necessary to add and remove users as they join and +leave the company. Perhaps most important from the user's perspective; +they do not need to enter a username or password if their workstation +is a member of an NT domain. The password hashes generated when they +logged on to their workstation will be negotiated during the initial +request for a session, passed through jCIFS, and validated against a +PDC or BDC. This also makes the user's domain, username, and password +available for managing session information, profiles, preferences, etc. +
  • +
  • The functionality used to authenticate and manage +arbitrary credentials has been exposed in the SmbSession and NtlmPasswordAuthentication +classes. This permits NTLM password authentication to be integrated +into applications without requiring Microsoft components or JNI. +
  • +
  • With the introduction of the jcifs.encoding property the client is now truly internationalized. It has been used successfully on OS/390 with native +EBCDIC character encoding. See the Sun JRE documentation for a list of supported +encodings. +
  • +
  • The URL issues remaining in the 0.6 series have been +fixed in 0.7 by converting all SMB URL handling internally to use the +java.net.URL class (Note: directories must now have a +trailing slash and Java 1.3 is required). Also a deadlock in the +name service code was identified and fixed (repaired in 0.6.8 as well). +
  • +
  • A copyTo() method has +been added to SmbFile that is very +fast at copying large directories across hosts. +
  • +
+There have been numerous other changes including the mkdirs() +and getType() methods, plain text password support (disabled +by default), the available() method and close() +fix for Named Pipes, reading files larger than 4 GB, the +NtlmAuthenticator class, and more. + +

All documentation has been completely reviewed. See the links under Developer Information at the top of the list to the left. + + + + +jcifs-0.6.8 released +posted by Mike, Thu Dec 19, 2002 + +This release fixes a name service deadlock. It was thought to have +been fixed in the previous release but an update was accidentally +lost. This is the same name service deadlock described in both the +stable and beta series for the past two releases. It should really be +gone now. + + + + +Java 1.3 Now Required +posted by Mike, Wed Nov 12, 2002 + +Java 1.3 is now required with jcifs-0.7.0b4 or later. This is because +we are now using the Java 1.3 variant of java.net.URL.set() for +all URL handling internally and the 1.2 implementation does not support +our requirements. Attempting to use Java 1.2 or below will result in an +error message printed to System.err and unknown protocol: +smb exceptions. If you must use Java 1.2 or 1.1 jcifs-0.6.8 +will work great as usual minus The URL Bug. + + + + +jcifs-0.7.0b5 released +posted by Mike, Tue Oct 22, 2002 + +To resolve URL issues, jcifs now uses java.net.URL internally +throughout. This has changed the behavior of the client in very +significant ways and it will undoubtedly break older code. These +issues are: +

    +
  • URLs that represent workgroups, servers, shares, or directories +must have a trailing slash '/'.
  • +
  • Canonicalization does not exceed the host component of the +URL. So smb://host/share/path/ + ../../../../foo/ is +canonicalized to smb://host/foo/ whereas previously the client +would have reduced this to smb://foo/.
  • +
  • For constructors that accept a second parameter, that parameter can +no longer be null.
  • +
  • Composing a URL with a workgroup and a second parameter like +smb://workgroup/ + server/share/path/ used to +be intelligent enough to eliminate workgroup. This +will now blindly compose the two arguments to give +smb://workgroup/server/share/path/ which is an illegal SMB URL.
  • +
+See CHANGES.txt for a more detailed explanation. +

+The NtlmHttpFilter and NetworkExplorer should +now work whereas before some users (largely Tomcat users) were +experiencing problems. The NTLM HTTP Authentication code is now +stateless and has been verified to work with both Resin and Tomcat +at least. An NtlmServlet has been contributed that can +negotiated NTLM SSP using older pre-2.3 servlet containers. Previously, +negotiated credentials could not be used to access SMB resources +with NetworkExplorer. This works now, and it is remarkably +fast, however you cannot filter NetworkExplorer with the +NtlmHttpFilter. The NTLM +HTTP Authentication document has been updated. + + + + +jcifs-0.6.6 released +posted by Mike, Thu Sep 26, 2002 + +There's a nasty bug in Win2K that causes jCIFS to hang. The +PrimaryDomain field in the SMB_COM_SESSION_SETUP_ANDX +response is not properly terminated with two zeros like it +should be when Unicode is negotiated. I have patched jCIFS to only +look for one zero which should eliminate this problem. +

+Unfortunately there are three other bugs that have not been attended +to as they all relate to the rather complicated issue of the SMB URL: +

    +
  • The URL protocol handler is not reentrant. It will produce +inconsistent results if java.net.URLs are created concurrently.
  • +
  • Full SMB URLs with an '@' in the path will misinterpret the +string following the '@' as the server component. This problem will +not occur if an SmbFile is composed with the two parameter +constructor or if user credentials are supplied.
  • +
  • There have been reports of a '/' being left out of SMB URLs being +created with the java.net.URL class. I have not been able to +reproduce this issue.
  • +
+These issues will be resolved all together with a new simpler State +Machine parser and properly integrated with the java.net.URL +class. I am not aware of any other bugs in 0.6.6 so please let us know +if you see otherwise. +
+
+ + +jcifs-0.7.0b12 released +posted by Mike, Tue Dec 31, 2002 + +Changes have been made that should eliminate the "unknown +protocol: smb" exceptions experienced when trying to install +jCIFS in environments using custom class loaders and restrictive +security policies (application servers). URL decoding of the +domain;user:password component of SMB URLs is in place. There +were a few other minor adjustments. + + + + +jcifs-0.7.0b11 released +posted by Mike, Fri Dec 20, 2002 + +A debugging statement at jcifs/UniAddress.java:173 was printing +useless information to System.out when listing smb:// +and smb://workgroup/ URLs. This has been fixed. +

+Although it remains to be seen how exactly jCIFS should be installed +for those using the jcifs.http package there do not appear to +be any issues remaining in the core. This will likely be the last beta. +

+Happy Holidays! + + + + +jcifs-0.6.8 released +posted by Mike, Thu Dec 19, 2002 + +This release fixes a name service deadlock. It was thought to have +been fixed in the previous release but an update was accidentally +lost. This is the same name service deadlock described in both the +stable and beta series for the past two releases. It should really be +gone now. + + + + +jcifs-0.7.0b10 released +posted by Mike, Fri Dec 13, 2002 + +Please read the FAQ. It now covers issues surrounding +the following Exception: +

+Exception MalformedURLException: unknown protocol: smb
+at java.net.URL.<init>(URL.java:480)
+at java.net.URL.<init>(URL.java:376)
+at java.net.URL.<init>(URL.java:330)
+at jcifs.smb.SmbFile.<init>(SmbFile.java:355)
+...
+
+Two deadlocks have been fixed (one serious one thought to have been +fixed in 0.7.0b7), minor adjustments to jcifs.Config have been +made to assist with the above exception, and the jcifs.encoding +property will now be read properly whereas previously it was not. +

+Also, notice there's an Old News ... link at +the bottom of the news section now. It's hard to believe it's been +less than three years since jcifs-0.1. + + + + +jcifs-0.7.0b9 released +posted by Mike, Fri Nov 22, 2002 + +An issue with getType() returning incorrect values and an issue +with the close() method of Named Pipe input and output streams +have been fixed. The NtlmAuthenticator has been reimplemented allowing +the SmbShell example to be restored to working order. +

+$ java -Djcifs.properties=../miallen.prp SmbShell smb://storage15/
+storage15/> cd admin$/
+Access denied for smb://storage15/admin$/
+username: nyrsch\Administrator
+password: fretos
+admin$/>
+
+
+
+ + +jcifs-0.7.0b8 released +posted by Mike, Wed Nov 13, 2002 + +Several bugs have been fixed regarding the getUncPath() +method not including the share name, failure connecting to Windows +98 via the Node Status call, and a NullPointerException in +UniAddress. The Authenticator functionality has not +be reimplemented but will in a later release. + + + + +Java 1.3 Now Required +posted by Mike, Wed Nov 12, 2002 + +Java 1.3 is now required with jcifs-0.7.0b4 or later. This is because +we are now using the Java 1.3 variant of java.net.URL.set() for +all URL handling internally and the 1.2 implementation does not support +our requirements. Attempting to use Java 1.2 or below will result in an +error message printed to System.err and unknown protocol: +smb exceptions. If you must use Java 1.2 or 1.1 jcifs-0.6.8 +will work great as usual minus The URL Bug. + + + + +jcifs-0.6.7 released +posted by Mike, Wed Nov 6, 2002 + +It's not clear that the name service deadlock can be provoked on the +0.6 series but I have applied the fix just to be safe. That's the +only change. + + + + +jcifs-0.7.0b7 released +posted by Mike, Mon Nov 4, 2002 + +A deadlock in the name service code was found and eliminated. The +SmbFiles created with listFiles() on a workgroup +resource like smb://workgroup/ were invalid (e.g. +smb://workrgoup/server/). The old correct behavior has been +restored. An issue regarding InetAddress mistaking certain +pathological names as IP addresses like the name '1' yielding IP 0.0.0.1 +has been fixed. + + + + + +jcifs-0.7.0b6 released +posted by Mike, Mon Oct 28, 2002 + +All encoding and decoding of 8 bit strings being read from or written to +a server will use an arbitrary encoding specified with the new +jcifs.encoding property. These changes will permit the client +to operate in any environment regardless of locale settings such as +OS/390 with a native EBCDIC file.encoding. +

+With the 0.7 series a bug was introduced that prevented workgroups, +servers of a workgroup, and shares of a server from being enumerated +using anonymous credentials. A concurrency issue with copyTo +was also identified. Both issues have been fixed. + + + + +jcifs-0.6.6 released +posted by Mike, Thu Sep 26, 2002 + +There's a nasty bug in Win2K that causes jCIFS to hang. The +PrimaryDomain field in the SMB_COM_SESSION_SETUP_ANDX +response is not properly terminated with two zeros like it +should be when Unicode is negotiated. I have patched jCIFS to only +look for one zero which should eliminate this problem. +

+Unfortunately there are three other bugs that have not been attended +to as they all relate to the rather complicated issue of the SMB URL: +

    +
  • The URL protocol handler is not reentrant. It will produce +inconsistent results if java.net.URLs are created concurrently.
  • +
  • Full SMB URLs with an '@' in the path will misinterpret the +string following the '@' as the server component. This problem will +not occur if an SmbFile is composed with the two parameter +constructor or if user credentials are supplied.
  • +
  • There have been reports of a '/' being left out of SMB URLs being +created with the java.net.URL class. I have not been able to +reproduce this issue.
  • +
+These issues will be resolved all together with a new simpler State +Machine parser and properly integrated with the java.net.URL +class. I am not aware of any other bugs in 0.6.6 so please let us know +if you see otherwise. +
+
+ + +SNIA CIFS Technical Reference Back Online +posted by Chris, Mon Sep 9, 2002 + +Following the restructuring of the Storage Networking +Industry Association (SNIA) website, the CIFS Technical +Reference disappeared for a while. A new home has been found and +the document is now back online. In the next few months, work will +begin on a TWiki[TM]-based comment forum so that interested +folk can annotate the SNIA CIFS doc. + + + + + +jcifs-0.7.0b3 released +posted by Mike, Sun Aug 25, 2002 + +As usual Chris found a couple of bugs testing in the interop +lab at the CIFS conferance. I fixed the graceful-reconnect +issue. Countless bugs have been fixed in Network Explorer. The NTLM HTTP +Authentication/Network Explorer docucumentation has been overhauled +again. Implemented mkdirs(), available() for Named +Pipes, and copyTo() will now attempt to maintain the last +modified time (although NT clearly doesn't support it). Quite a few +other issues fixed including one quite serious bug. + + + + +NTLM HTTP Authentication and the New <tt>jcifs.http</tt> Package +posted by Mike, Wed Aug 8, 2002 + +With the release of the 0.7.0 series, we are introducing a new +package; jcifs.http. The jCIFS client is proving to be quite +useful for adding functionality to websites on corporate intranets. +Adding a link to a document on your LAN for example is a trivial +exercise with jCIFS. In the jcifs.http package we will be +providing Servlets and CGIs that do this and more. +

+To inaugurate this package, we have implemented NTLM HTTP +Authentication which allow MSIE clients to authenticate against a domain +controller. This is a useful feature because many of the tasks +surrounding user management now fall back to computer support and HR. It +is not necessary to add and remove users as they join and leave the +company. Perhaps most important from a user's perspective; they do not +need to enter a username or password if their workstation is a member of +the domain. The password hashes generated when they logged on to their +workstation will be negotiated during the initial request for a session, +passed through jCIFS, and validated against a PDC or BDC. This also +makes the users domain, username, and password available for managing +session information, profiles, preferences, etc. +

+For complete details, please read Authenticating MSIE Clients using NTLM HTTP Authentication and jCIFS. +

+We would be delighted to see popular application servers use the now +public SmbSession +class's getChallenge() and logon() methods to +integrate this functionality into their products in a way that is +consistent with other authentication schemes such as BASIC_AUTH +so that getRemoteUser() works expectedly or provide for NTLM +HTTP Authentication protected "Relms" in Tomcat. + + + + +jcifs-0.7.0b released +posted by Mike, Wed Aug 8, 20002 + +New features: +

    +
  • NTLM HTTP Authentication. Thanks to Jason Pugsley for his code and +bringing us up to speed on this. I know this will be a popular feature. +See above message for details.
  • +
  • A jcifs.smb.client.codepage property has been added to +specify an 8 bit character encoding to use for "ASCII" strings. +If your workgroup, server, and share names are not rendered properly you +may wish to explore this. See CHANGES.txt +for details. This should resolve the issue reported by Dmitry Khlonin +about using codepage=Cp866 on his Russian LAN. See the Supported +Encodings page in the Sun JRE documentation for a list of valid +identifiers.
  • +
  • Added an SmbFile.getType() which will return one of the +following type identifiers: +
    +SmbFile.TYPE_WORKGROUP
    +SmbFile.TYPE_SERVER
    +SmbFile.TYPE_SHARE
    +SmbFile.TYPE_NAMED_PIPE
    +SmbFile.TYPE_PRINTER
    +SmbFile.TYPE_FILESYSTEM
    +
    +isWorkgroup() is now deprecated.
  • +
  • Added a "lookup" table to jcifs.netbios.NbtAddress like the +one in java.net.InetAddress to prevent redundant queries from +reaching the wire.
  • + +
  • Plain text passwords have been implemented but must be enabled with +jcifs.smb.client.disablePlainTextPasswords=false. This is +true by default and will generate a "Plain text passwords are +disabled" RuntimeException exception if you try to use it.
  • + +
  • The SmbFile.length() method now returns the capacity of the +disk for a share. So getType() must be +SmbFile.TYPE_SHARE.
  • + +
  • Added an SmbFile.freeDiskSpace() method that reports the +amount of free disk space in bytes on a disk exported by a share.
  • + +
  • Added an SmbFile.copyTo() method. This method can copy +directories across hosts very quickly however at the moment it +does not mirror file attributes. See the end of this +message for details.
  • + +
  • Replaced the AuthHandler interface and AuthInfo +with the abstract NtlmAuthenticator and +NtlmPasswordAuthentication classes to be consistent with the +Authenticator and PasswordAuthentication classes from +the java.net package. The underlying behavior remains the same +however it has not been tested thoroughly.
  • +
+
+
+ + + +jcifs-0.6.5 released +posted by Chris, Sun Jun 2, 2002 + +A file corruption bug, which occurred only when writing to Novell's CIFS +implementation for NetWare, was found and fixed. (Novell has been +notified about this problem; good work Mike and Tony!) Also fixed was a +file truncation bug introduced in 0.6.2 (with the return -1 fix). + + + + +jcifs-0.6.3 released +posted by Mike, Fri May 3, 2002 + +The SMB URL issues with reserved characters and Unicode (e.g. Japanese) +have been resolved. It is no longer necessary to URL encode or decode +pathnames. Instead, these characters must be encoded for the authority +component (actually just '@' with '%40'). A problem with +passwords longer than 14 characters has also been fixed. + + + + + +SNIA CIFS Technical Reference 1.0 Released +posted by Chris, Wed Apr 3, 2002 + +According to a +message on the Samba Technical mailing list, the Storage Network Industry Association +will soon release version 1.0 of their SMB/CIFS Technical Reference. +Version 0.9 has been available for quite some time. The new release +contains several corrections and updates. + + + + +jcifs-0.6.2 released +posted by Mike, Thu Mar 21, 2002 + +Two minor bugs have been fixed. Please see CHANGES.txt for details. + + + + +New version of jCIFS-based SMB-Browse for MacOS X +posted by Chris, Tue Mar 5, 2002 + +Version 0.8: +
    +
  • Mounting of shares with spaces in the share name now works,
  • +
  • German and French version are now included,
  • +
  • Domain and Workgroup logins are now working correctly.
  • +
+ +See: http://www.shukwit.com/main.php +
+
+ + +Serious Bug Fixed: jcifs-0.6.1 released +posted by Mike, Thu Feb 21, 2002 + +A bug has been found that affects all previous versions of jCIFS. Users +are advised to upgrade to 0.6.1 immediately. If a file is retrieved +using the SmbFileInputStream class, the file's size is +precisely a multiple of 4096 and the byte[] b and int +len parameters used in a read() operation are both +larger than 4096, the read( byte[] b ) and read( +byte[] b, int off, int len ) methods will return -1. + + + + +jcifs-0.6.0 released +posted by Mike, Wed Feb 20, 2002 + +The jcifs-0.6.0 package is ready. The most significant improvement since 0.5 is performance. +

+Performance: +

+The performance improvements leading up to the 0.6 release have proven +to be significant. Raw transfer rates have not changed but listing +large directories, crawling over several hosts with multiple threads, +querying attributes on lists of files, and otherwise IO and multiplexing +intense operations have improved 800%+ in some cases. This release illustrates how a +carefully considered design can greatly improve the performance of an application. These +speed improvements are the result of reorganizing how buffers are used +(now only two per VM rather than per connection), elimination of +unnecessary network messages with smarter driver logic, +attribute caching, and analyzing spots where objects were being created +and destroyed frequently. This new client can crawl over every file +on my NT workstation in a hair over 10 seconds. +

+Even though the focus for 0.6.0 was cleanup, refactoring, and +performance, there are a few new features worth mentioning. Here's +a breakdown. +

+New Features: + +

    +
  • The listFiles methods have been added which offer +a significant speed boost for operations that intensively query the +attributes of each file in the list.
  • +
  • Many of the SmbFile +methods throw the now public +SmbException.
  • +
  • An AuthHandler +interface and +SmbAuthException +have been introduced for handling authentication related error +conditions.
  • +
  • The name service code has been generalized to handle +both DNS and NetBIOS name services much more smoothly +(0.5 handles this incorrectly actually) using the new +UniAddress.
  • +
  • The client can now list the hosts of a workgroup/ntdomain on remote +networks; you can enumerate an entire WAN.
  • +
  • The client is a lot smarter about how to ultimately service requests.
  • +
  • Graceful reconnect.
  • +
  • Support for Novell NetWare.
  • +
+
+
+ + + +Related Projects of Note +posted by Chris, Tue Feb 12, 2002 + +These are project related, in various ways, to the work we are doing +with jCIFS: + +

+

    +
  • SMB Browse allows browsing +of the Network Neighborhood from a Mac OSX system. The software is +written in Cocoa-Java, and uses jCIFS to provide access to the SMB +browse list.
  • +
+ +Version 0.6 of SMB Browse +has been released, with 0.7 planned soon. +
+
+ + +jcifs-0.6b9 released +posted by Mike, Wed Feb 6, 2002 + +There have been two bug fixes, some unnecessary code has been removed, +logic preventing certain invlid operations (e.g. list() +on IPC$) has been added, and the documentation has been +updated. The API documentation still needs a little more work, but +we think that should be it for this long string of betas. Thanks to +everyone who provided feedback. + + + + +New Mirror +posted by Chris, Sun Jan 20, 2002 + +We have started mirroring the source archive here on +the root server. This should reduce the problems we've had in the past +when one or the other server is down or unreachable. The mirror is +updated once daily. + + + + +jcifs-0.6b8 realeased +posted by Mike, Sat Jan 12, 2002 + +I forgot to convert the delete operation to use listFiles. +

+Beta8 handles this properly on NT as well as Win98 and probably most +other servers including NetWare. Deleting directories should also be +faster. I also fixed an issue where testing exists() on a +newly created directory would incorrectly return false. I just needed to +manually expire the attrExpiration after the mkdir +call to cause the client to check the server again. + + + + +Updated SMB URL Internet Draft +posted by Chris, Sat Jan 12, 2002 + +The SMB +URL Internet Draft has been updated. The new draft includes support +for the :port field, and the use of query strings to specify +NBT context (WINS server, Called Name, etc.) The document provides a +fixed set of keywords that may be used within the query section of the +URL string. It would be nice to have a third-party authority placed in +charge of accepting updates to the keyword list. Unfortunately, the +keywords must be interpreted by the client rather than the +server, so adding new keywords without some sort of public comment +process would cause some clients to break. +

+The new draft does not include any support for SMB over native +TCP (port 445 semantics). This is still an area for discussion. While +it is clear that adding support for non-NBT file services would be easy, +no one yet (including myself) has provided a mechanism for efficiently +browsing services within a W2K Domain via the SMB URL. This may turn +out to be trivial, but it won't go into the specification until it is +shown that it can be done. + + + + +jcifs-0.6b7 released +posted by Mike, Fri Jan 11, 2002 + +The introduction of listFiles in a previous beta created +an issue with caching file attributes and enumerating workgroups +and hosts of a workgroup. There was a compilation problem with +URLDecoder and a possible NullPointerException +in the graceful reconnect code. Generally the last beta was a flop. We +strongly advise that you erase it and use this release. We have high +hopes for it. The good news is listFiles has turned out +to be quite a screamer on regular directories. I can list every file +on my NT machine with T2Crawler in 10.095 seconds (yes, +over the network). + + + + + +jcifs-0.6b6 released +posted by Mike, Mon Jan 7, 2002 + +There have been quite a few bug fixes. The listFiles() +methods no longer throw MalformedURLException or +UnknownHostException. The client can now recover from +a server being restarted or unavailable between calls (and might +solve your invalid UID problem TN). A URL decoding issue, some +unnecessary AuthExceptions, and Win98's preference for +capitalized share names have also been fixed. Lot's of detail in the +README.txt +if you're interested. + + + + + +jcifs-0.6b5 released +posted by Mike, Wed Dec 19, 2001 + +Dispite being in the middle of a beta cycle we have implemented a new +freqently requested feature. The SmbFile class now has two +listFiles methods. The normal java.io.File +like listFiles method will return an array of +SmbFiles. The other will take a DOS "wildcard" expression +with '?' and '*' meta characters. The SmbShell example +now sports pretty formatted output to complement this feature: +

+winnt> ls c?o*
+clock.avi                  -rw--      82944 Mon Oct 14 1996 1:38 AM
+Cookies                    drw--          0 Fri Nov 13 1998 9:42 PM
+2 items in 5ms
+
+I have written a document on Exceptions +and the AuthHandler Interface . The auditorymodels.org site appears +to have stablized. It has a new static IP so we should be able to use +that as our download area once again. +
+
+ + +jcifs-0.6b4 released +posted by Mike, Sat Dec 15, 2001 + +This beta 4 fixes a serious bug that caused exists() and +the several methods that called it to return erroneous results. There +have also been quite a few other smaller bug fixes. This release should +be fairly stable. The example and test programs have been updated +and retested without incedent. +

+It has recently been decided that the next beta will introduce +the listFiles methods. This will prolong the beta +cycle however the issue has been raised enough that it is now +considered a bug. A wildcard FilenameFilter and possibly +FileFilter will also be implemented. + + + + + +jcifs-0.6b3 and auditorymodels.org +posted by Mike, Wed Nov 28, 2001 + +The beta 2 release has a deadlock in it so you might want to +try jcifs-0.6b3. This code should prove to be even faster +than the first beta. I have changed from using two buffers for +each transport to two buffers for all transports with a main +synchronized(buf) around it. This serializes reads +and writes for all sockets but, surprisingly, it appears to be +even faster. I've been tweaking the crawler example to use as a +benchmark. There's a new example T2Crawler that can +enumerate every share on a segment in a matter of seconds. +

+You may have noticed that the auditorymodels.org site is not available. +AT&T switched IP's on that cable modem. Looks like it might take +a while. I've mirrored everything over to my ISP's account for +now. Please let me know if you find any bad links. + + + + +jcifs-0.6b2 released +posted by Mike, Wed Nov 21, 2001 + +Previously, jCIFS could not enumerate hosts of a +workgroup/domain if that workgroup/domain was on a different +network segment. This problem has fixed. This beta of the +jCIFS client can enumerate the complete hierarchy of an entire WAN provided +your network supports it. Two trivial bugs have also been fixed. + + + + + +jcifs-0.6b released +posted by Mike, Fri Nov 16, 2001 + +There have been significant changes under the hood and to +the API. The name service bug has been fixed, most of the +top level code has been re-written to be much smarter, and most +of SmbFile's methods throw the now public SmbException. +This refactoring has resulted in marked performace +improvements (100%+ in some cases). See the README.txt +for important details about how to modify your code. Keep in mind the +sooner you find the bugs the sooner they get fixed so we can move on. + + + + + +Bug in Mixed Mode DNS/NetBIOS Name Resolution Code +posted by Mike, Thu Oct 18, 2001 + +If a DNS name longer than 15 characters is used with a +resolveOrder that has DNS after +WINS or BCAST (the default of +resolveOrder=LMHOSTS,WINS,BCAST,DNS qualifies) the +name will incorrectly get truncated to 15 characters. In short, +the name query will fail and jCIFS will not be able to connect to +the host. The only solution at the moment is to use DNS +before WINS and BCAST or do not use both +types of resolution simultaniously. +

+This has prompted a bit of refactoring, reducing, rewriting, general +cleanup, comments ... etc (everywhere, not just in the above mentioned +resolver code). The result will be 0.6. This means no new features +but it will mean a more robust, leaner, and faster jCIFS. This release +will also break bytecode compatabilty. +

+If you think of anything you consider to be "broken" in +jCIFS, even if it is not technically a bug, now is the time to +send a message to the jCIFS mailing list +with an explaination of the issue. + + + + + +jcifs-0.5.1 released +posted by Mike, Mon Aug 27, 2001 + +Chris found three minor bugs while testing in the CIFS Conference +Interoperabilty Lab. A detailed description of these issues and their +resolutions is posted here. +These packages will also now work with both Java 1.1 as well as Java2. + + + + +Success at the CIFS Conference +posted by Chris, Sun Aug 25, 2001 + + +I presented jCIFS at +the 2001 CIFS Conference and +PlugFest, which was held August 20 - 24 in Bellevue, +Washington (a suburb of Redmond). +

+I met up with the Australian contingent of the Samba Team on Sunday, +the day before the PlugFest started. We all went out to the hotel pool +on what proved to be the only warm and sunny day of the week. The plan +was to relax and spend some time swimming, but Tridge got the idea of +setting up a Wireless Access Point so we could all sit by the pool with +our laptops. I think we spent five hours trying to get the modem in the +Apple Airport to dial out and authenticate properly. We never did get +it working (and I never got into that pool). Eventually, we used +Tridge's Linux Laptop to dial in, hard-wired that to the Airport, and +used the Airport's DHCP service to hand out unrouted IPs. It was a bit +of a hack but it worked. +

+The PlugFest started Monday. Many CIFS vendors were present, +including some new faces, and I was able to test jCIFS against a large +variety of servers. Some jCIFS bugs were discovered (and squashed) and +I was also able to demonstrate the utility of jCIFS as a test client. +The ease with which new torture tests can be written makes jCIFS an +excellent tool for server verification. +

+A number of issues were discussed at the Conference, including the +current status of the SNIA +CIFS document which has been downgraded from a Specification to a +Technical Reference. The SNIA is also +looking for CIFS compatibility testing tools to help CIFS implementors +verify their products, so (as time permits...and it typically doesn't) I +will be looking at writing and documenting some more formal jCIFS test +suites. + + + + +Java 2 No Longer Required +posted by Mike, Thu Aug 9, 2001 + +Actually, it never was. I just never bothered to try. I had to comment +out one (1) line. Oops. +

+It has been built with the Blackdown jdk_1.1.6-v2, however any +1.1 version should work fine. For your convenience, I have uploaded a +jar. + + + + +jcifs-0.5b2 released +posted by Mike, Fri Jul 13, 2001 + +Some flags specified when opening files were not optimal. Trying +to open the same file twice would fail even though the file +was opened only for reading. This has been fixed. Also, a +new Log.CRITICAL_EXCEPTIONS mask has been added +to turn off common non-critical exceptions from +being printed to the console. See the second to last line of examples/ThreadedSmbCrawler.java +for an example of how to set this mask. + + + + + +jCIFS 0.5 is Now Final +posted by Mike, Sun Jul 29, 2001 + +The 0.5 series is complete. This is the most stable and +full featured CIFS client library that that we have to +offer. There are no known bugs and it has been tested very +thoroughly. A minor bug in SmbFile.renameTo() +has been fixed (did not return false when it should have) +and API +Documentation improvements have been added. Thanks deserved to +everyone who helped. + + + + +jcifs-0.5b2 released +posted by Mike, Fri Jul 13, 2001 + +Some flags specified when opening files were not optimal. Trying +to open the same file twice would fail even though the file +was opened only for reading. This has been fixed. Also, a +new Log.CRITICAL_EXCEPTIONS mask has been added +to turn off common non-critical exceptions from +being printed to the console. See the second to last line of examples/ThreadedSmbCrawler.java +for an example of how to set this mask. + + + + +jcifs-0.5b released +posted by Mike, Fri Jun 29, 2001 + +The 0.5 series is now beta. New features include the proper fix for the SmbFile.list() bug, share, server, and workgroup enumeration, Named Pipes, a complete implementation of the SMB Filesharing URL Scheme IETF draft, and more. See the README for details. This release is already been through a stable iteration and there are no known bugs. + + + + +CIFS Conference! +posted by Chris, Fri Jun 22, 2001 + + +The 2001 CIFS Conference and Plugfest +will be held August 20 - 24 in Bellevue, +Washington (a suburb of Redmond). There will be a bigbunch +of CIFS developer's present. This is the main event for the CIFS +community. + + + + + +jcifs-0.5dev3 released +posted by Mike, Thu Jun 21, 2001 + +No new features. Just many sorely needed bug fixes. The jcifs-0.5dev2 +release has some pretty serious problems. This release should be +much better. It passes all my torture tests anyway. There +is some documentation on using jCIFS with Win32 Named Pipes here. I +have also writtin a crude SmbCrawler +program that might help admins map out their network. Use + +

+java -Djcifs.properties=my.prp ThreadedSmbCrawler smb://myworkgroup 2 10
+
+ +to enumerate over all servers and their shares (depth 2) with 10 threads. +
+
+ + +jcifs-0.5dev2 released +posted by Mike, Mon May 21, 2001 + +Lots of new stuff including enhanced +server name resolution with DNS, lmhosts files, specifying a +"resolve order", Named Pipes (Paul) and Transact Named Pipes, +a daylight savings time bugfix and time encoding bugfix (Urban), +documentation improvements, Unicode alignment proper (fixes the +smb://, smb://name enumeration problem with +Samba), SmbFile method behavior finalization, quick exit +of programs (used to hang for 15sec), and more. Of course this is all +totally untested so try it out and let us know how it goes. + + + + + +Bug in jcifs-0.4 SmbFile.list() Method +posted by Mike, Fri May 11, 2001 + +There is a serious bug in NT and NT Server that can +cause the SmbFile.list() method to get +caught in an endless loop consuming major cpu cycles +and bandwidth. The problem is described in more detail here. +

+There is no fix except to not call SmbFile.list(). Do not +use jcifs-0.4 in a production environment if your application uses this +method. The bug has been properly fixed in jcifs-0.5dev1, however this +version is highly experimental and has known bugs of it's own. We are +sorry for any inconvenience this may have caused. + + + + + +jcifs-0.5dev1 released +posted by Mike, Sun Apr 8, 2001 + +We now embark on the first experimental series of +what will become jcifs-0.5. New features include the +Transactions API, batching, and workgroup, server, +share enumeration. Tunable batching, which is described here, +should only be of interest to CIFS developers. What should +intrest most people is that jCIFS now has the ability to enumerate +workgroups of a network, servers of a workgroup, and shares of a +server with smb://, smb://workgroup, +and smb://server URLs respectively. For example +the url smb://storage15 will list the shares +available on the server storage15. This makes SmbShell +start to look pretty slick because you can cd all around +your network. + + + + + +New CIFS Draft Specification Posted +posted by Chris, Wed, Apr 4, 2001 + +The Storage Network Industry Association (SNIA) has posted a draft +specification for the SMB/CIFS protocol. This draft is based on +earlier work by Paul Leach and Dilip Naik of Microsoft, but has been +updated. The draft is currently in 30-day review. + + + + + +jCIFS Demonstrated at Connectathon 2001 +posted by Chris, Sat Mar 31, 2001 + + +jCIFS 0.4-final was demonstrated and tested at Connectathon 2001 with +overall good results. Some problems were discovered, of course, and +solutions are planned for 0.5. +

+The jCIFS Team is interested in continued testing against commercial +SMB/CIFS implementations, particularly derivatives of Advanced Server +for Unix. Please let us know if you can generate sniffer output for +us to look at. (TCPdump and/or Microsoft NetMon formats for input into +Ethereal are preferred.) + + + + +jCIFS 0.4 is Now Final +posted by Mike, Fri Feb 16, 2001 + +The jCIFS 0.4 series is now final. All of the idiosyncrasies of the +various platforms have been worked out and overall performace is +good. There are no known bugs but a couple of minor ones have +been fixed. + + + + + +jcifs-0.4b3 released +posted by Mike, Sat Feb 10, 2001 + +Heavily threaded torture test programs have revealed elusive +reentrance problems and prompted total retooling of lower io +layers. The name service code was particularly troubled. Special +thanks to Paul for his help with this. There are also several +other minor bug fixes and general spit and polish. See the README +for details. + + + + + +More Bugs Fixed: jcifs-0.4b2 released +posted by Mike, Sat Jan 20, 2001 + +More bug's have been revieled and squashed. Thanks to all who have helped +with beta testing this. It should be pretty stable at this point. See +the README for details but you should upgrade regardless. + + + + +Bug Fixed: jcifs-0.4b1 released +posted by Mike, Wed Jan 4, 2001 + +A serious bug was discovered and fixed. The new packages are +in the download directory. If two different host names where +queried quickly back to back the returned names could get mixed +up because the transaction id used to coordinate concurrent name +service queries was not being incremented. Thank's to the Ant build tool +new packages where built and up in no time flat. + + + + +jcifs-0.4b released +posted by Mike, Wed Jan 3, 2001 + +The jcifs client is now stable and ready for use. This is not +"infrastructure" anymore. It _should_ work flawlessly. I got +rid of quiet a bit of fat such as that "Demultiplexer" thing I +preached for two months :~) I took Chris' advice and created our +own normalized abstraction based on the java.io.File class for +the API. There's no XFile accessor but the URL protocol handler +is in place. This is NOT alpha code and it will only be beta +until I get some confirmation that it works for everybody. If you +have any problems get on the mailing list. Eveything's in the src directory. Happy +New Year! + + + + +Licensing Model +posted by Chris, Mon Jul 24, 2000 + +After much debate, we have decided to use the GNU LGPL to license the +jCIFS class library. There are issues to +consider when using the regular GPL to license Java code. +See also GNU's Java pages. + + + + +jcifs-0.3a released +posted by Mike, Thu Jul 20, 2000 + +Lotta plumbing, finalized the server message block infrastructure, +implemented some of XFileAccessor as well as URLStreamHandler, +batching works great, replaced NbtSession with NbtSocket class that +extends java.net.Socket(this is the way it should have been done), and +more. Feel free to browse +the source as usual. Still alpha code. + + + + +jcifs-0.2a released +posted by Mike, Sun Jun 18, 2000 + +Quite a range of new things but still just preliminary code(ie +can't transfer a file). Mainly the new packet construction/deconstruction +code has been implemented throughout(a joy to work with now). There's also +some smb foundation code, server componentry and much more. + + + + +jcifs-0.1 released +posted by Mike, Wed Mar 15, 2000 + +The NetBIOS client implementation is complete. + + + + + + +Download +JCIFS NTLM HTTP Authentication +The FAQ +Mailing List Archive (GMANE) +Obtaining a Network Packet Capture + + +Developer Information + +JCIFS API Documentation +Setting Client Properties +Setting Name Resolution Properties +Using JCIFS to Connect to Win32 Named Pipes +JCIFS Exceptions and NtlmAuthenticator +Using JCIFS NTLM Authentication for HTTP Connections +JCIFS is Licensed Under the LGPL + + + +Related Java Projects + + +j-interop - Java COM Interop (uses Jarapac) +sharehound - CIFS network search engine +IntegraTUM WebDisk - HTTP to CIFS gateway +jcifs-ext - JCIFS Extensions +Jarapac - DCE/RPC in Java +The Jacob Project - Java/COM Bridge +JNBridge - Java/.NET Bridge +J-Integra - DCE/RPC in Java +Davenport - WebDAV to CIFS gateway +Alfresco JLAN Shared File Drive Interface + + + +CIFS Authorities + +http://www.samba.org/ +http://www.samba-tng.org/ + + + +Other CIFS Utilities and Tools + +Samba for Amiga +Sharity-Lite +SMB Browse for MacOSX +Xamba Network Integration Project + + + +MSRPC +Rpcdump utility for querying RPC servers +OpenGroup DCE/RPC Specification +OpenGroup DCE/RPC Specification - NDR +What OLE Is Really About + + + +Kerberos +RFC1510 - Kerberos V5 Specification +How a Kerberos Logon Works in Win2K +JGSS Example +Kerberos Explained +W2K PAC Specification + + + +Technical Documentation + +"Implementing CIFS" (complete online book) +Annotated CIFS Specification: draft-leach-cifs-v1-spec-02.html +SNIA CIFS Technical Reference (V1.0) +The NTLM Authentication Protocol +A .NET Developer's Guide to Windows Security +Windows System Error Codes +Windows Network Management Error Codes +rfc1001 - NetBIOS Concepts and Methods +rfc1002 - NetBIOS Detailed Specifications +CIFS Explained (A whitepaper by John Kleven) +SMB URL draft specification V07 +NetBIOS, NetBEUI, NBF, SMB, CIFS networking links page +Microsoft Writeup on WINS behavior +Microsoft Writeup on WINS under W2K +Microsoft Server Documentation on Browsing WANs using WINS +Windows IT Library: NT Network Plumbing +Thursby Software's CIFS pages +Linux Mag: Understanding the Network Neighborhood + + + +Other + +Join the JCIFS Mailing List +Browse the Source +Batching +http://www.gnu.org/ +http://www.opensource.org/ +Microsoft's CIFS Mailing List Archives + + + + diff --git a/docs/mkjavadoserror.sh b/docs/mkjavadoserror.sh new file mode 100644 index 0000000..dcbfeba --- /dev/null +++ b/docs/mkjavadoserror.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +./csvprint -f -s '\t' doserror.txt " public static final int %5 = %3;\n" +echo +./csvprint -f -s '\t' doserror.txt " %5,\n" +echo +./csvprint -f -s '\t' doserror.txt " \"%5\",\n" +echo +./csvprint -f -s '\t' doserror.txt " \"%6\",\n" +echo +./csvprint -f -s '\t' doserror.txt " { %3, %4 },\n" diff --git a/docs/mkjavantstatus.sh b/docs/mkjavantstatus.sh new file mode 100644 index 0000000..8e2e7d4 --- /dev/null +++ b/docs/mkjavantstatus.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +csvprint -f -s ' ' ntstatus.txt " public static final int %3 = %1;\n" +echo +echo " static final int[] NT_STATUS_CODES = {" +csvprint -f -s ' ' ntstatus.txt " %3,\n" +echo " };" +echo +echo " static final String[] NT_STATUS_MESSAGES = {" +csvprint -f -s ' ' ntstatus.txt " \"%4\",\n" +echo " };" + diff --git a/docs/mkjavawinerr.sh b/docs/mkjavawinerr.sh new file mode 100644 index 0000000..f2db516 --- /dev/null +++ b/docs/mkjavawinerr.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +./csvprint -f -s '\t' winerr.txt " public static final int %2 = %1;\n" +echo +echo " static final int[] WINERR_CODES = {" +./csvprint -f -s '\t' winerr.txt " %2,\n" +echo " };" +echo +echo " static final String[] WINERR_MESSAGES = {" +./csvprint -f -s '\t' winerr.txt " \"%3\",\n" +echo " };" + diff --git a/docs/nbtcodes.html b/docs/nbtcodes.html new file mode 100644 index 0000000..3ffa563 --- /dev/null +++ b/docs/nbtcodes.html @@ -0,0 +1,111 @@ +NetBIOS Hex Codes + + +

NetBIOS Hex Codes

+ +The NetBIOS naming convention allows for 16 characters in a NetBIOS name. +Microsoft, however, limits NetBIOS names to 15 characters and uses the +16th character as a NetBIOS suffix. + +

All NetBIOS names are 16 characters in length. A NetBIOS suffix is the +16th character of the 16-character NetBIOS name. The NetBIOS suffix is +used by Microsoft Networking software to identify functionality installed +on the registered device. + +

The following table lists the NetBIOS suffixes that are used by Microsoft +Windows NT. The suffixes are listed in hexadecimal format because many of +them are unprintable otherwise. + +

+Name                Number(h)  Type  Usage
+--------------------------------------------------------------------------
+<computername>         00       U    Workstation Service
+<computername>         01       U    Messenger Service
+<\\--__MSBROWSE__>     01       G    Master Browser
+<computername>         03       U    Messenger Service
+<computername>         06       U    RAS Server Service
+<computername>         1F       U    NetDDE Service
+<computername>         20       U    File Server Service
+<computername>         21       U    RAS Client Service
+<computername>         22       U    Microsoft Exchange Interchange(MSMail
+                                     Connector)
+<computername>         23       U    Microsoft Exchange Store
+<computername>         24       U    Microsoft Exchange Directory
+<computername>         30       U    Modem Sharing Server Service
+<computername>         31       U    Modem Sharing Client Service
+<computername>         43       U    SMS Clients Remote Control
+<computername>         44       U    SMS Administrators Remote Control
+                                     Tool
+<computername>         45       U    SMS Clients Remote Chat
+<computername>         46       U    SMS Clients Remote Transfer
+<computername>         4C       U    DEC Pathworks TCPIP service on
+                                     Windows NT
+<computername>         52       U    DEC Pathworks TCPIP service on
+                                     Windows NT
+<computername>         87       U    Microsoft Exchange MTA
+<computername>         6A       U    Microsoft Exchange IMC
+<computername>         BE       U    Network Monitor Agent
+<computername>         BF       U    Network Monitor Application
+<username>             03       U    Messenger Service
+<domain>               00       G    Domain Name
+<domain>               1B       U    Domain Master Browser
+<domain>               1C       G    Domain Controllers
+<domain>               1D       U    Master Browser
+<domain>               1E       G    Browser Service Elections
+<INet~Services>        1C       G    IIS
+<IS~computer name>     00       U    IIS
+<computername>         [2B]     U    Lotus Notes Server Service
+IRISMULTICAST          [2F]     G    Lotus Notes
+IRISNAMESERVER         [33]     G    Lotus Notes
+Forte_$ND800ZA         [20]     U    DCA IrmaLan Gateway Server Service
+
+
+ +

NetBIOS name types describe the functionality of the registration. + +

Unique (U): The name may have only one IP address assigned to it. On a +network device multiple occurrences of a single name may appear to be +registered. The suffix may be the only unique character in the name. + +

Group (G): A normal group; the single name may exist with many IP +addresses. WINS responds to a name query on a group name with the limited +broadcast address (255.255.255.255). Because routers block the +transmission of these addresses, the Internet Group was designed to +service communications between subnets. + +

Multihomed (M): The name is unique, but due to multiple network interfaces +on the same computer this configuration is necessary to permit the +registration. The maximum number of addresses is 25. + +

Internet Group (I): This is a special configuration of the group name used +to manage Windows NT Domain names. + +

Domain Name (D): New in Windows NT 4.0. + +

For additional information, please see the following article in the +Microsoft Knowledge Base: + +

+   ARTICLE-ID: Q119495
+   TITLE     : List of Names Registered with WINS Service
+
+   ARTICLE-ID: Q154608
+   TITLE     : NETBIOS Node Status Query Returns First Instance of Unique
+               Name
+
+   ARTICLE-ID: Q129603
+   TITLE     : Using Systems Management Server Remote Control over a RAS
+               Server
+
+Additional query words: nbtstat netbeui browse browsing limitation length
+======================================================================
+Keywords          : msnets kbnetwork
+Version           : 3.5 3.51 4.0
+Platform          : winnt
+======================================================================
+
+Copyright Microsoft Corporation 1998. + + + + diff --git a/docs/new.gif b/docs/new.gif new file mode 100644 index 0000000..ede003b Binary files /dev/null and b/docs/new.gif differ diff --git a/docs/ntlmhttpauth.html b/docs/ntlmhttpauth.html new file mode 100644 index 0000000..c11be10 --- /dev/null +++ b/docs/ntlmhttpauth.html @@ -0,0 +1,615 @@ + + + + + + + + + +

JCIFS NTLM HTTP Authentication

+ + + +IMPORTANT: All HTTP related code and corresponding documentation in JCIFS is not supported, no longer maintained and will be removed because it is broken and obsolete (and because HTTP has nothing to do with CIFS). This page remains only for informational purposes and for legacy users. +

+The HTTP "filter" in particular uses a "man in the middle" technique that cannot support NTLMv2. Since late 2008, users have started to report that client security policy is requiring NTLMv2 and that this solution no longer works. For this reason and others described in this post, this feature will be removed from the JCIFS package. +

+Currently we recommend using Jespa which properly implements NLTMv2 server side authentication and includes an advanced NTLMv2 HTTP SSO Servlet Filter. +
+ +

+A common requirement of websites on corporate Intranets is NTLM HTTP authentication also sometimes referred to as Single Sign On (SSO). Microsoft Internet Explorer has the ability to negotiate NTLM password hashes over an HTTP session using base 64 encoded NTLMSSP messages. This is a staple feature of IIS but Java application servers too can use jCIFS to authenticate MSIE clients against a domain controller. This is a useful feature because many of the tasks surrounding user management now fall back to computer support and HR. It is not necessary to add and remove users as they join and leave the company. Perhaps most important from a user's perspective; they do not need to enter a username or password if their workstation is a member of the domain. The password hashes generated when they logged on to their workstation will be negotiated during the initial request for a session, passed through jCIFS, and validated against a PDC or BDC. This also makes the users domain and username available for managing session information, profiles, preferences, etc. Using the jCIFS Servlet Filter it is trivial to add NTLM HTTP authentication support to your site. It is also possible to build custom authentication modules using the NtlmSsp classes directly. This Filter scales very well primarily because sessions are multiplexed over transports. But this functionality is not without caveats. + + + + +Note: This functionality is a non-conformant extension to HTTP conceived entirely by Microsoft. It inappropriately uses HTTP headers and therefore may not work with all Servlet containers or may stop working with a new release of your application server. Also, this flavor of password encryption is not very secure so under no circumstances should it be used to authenticate clients on the Internet. + +

+ +Note: Don't forget to restart the container after changing jCIFS init-parameters. JCIFS must use the container class loader and jCIFS properties are only read once when jCIFS classes are initialized. + + + +

Installation and Setup

+ +Put the latest jCIFS jar file in the lib/ directory of your webapp [1]. Because jCIFS properties are loaded once when the jCIFS classes are first accessed, it is necessary to actually stop and restart the container if any jCIFS properties have been changed. Create a filter section in your web.xml. Some example web.xml filter sections follow. + +

Production web.xml Example

+ +A minimalistic web.xml file with filter and filter-mapping directives might look like the following: + +
+<filter>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <filter-class>jcifs.http.NtlmHttpFilter</filter-class>
+
+    <init-param>
+        <param-name>jcifs.netbios.wins</param-name>
+        <param-value>10.169.10.77,10.169.10.66</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.domain</param-name>
+        <param-value>NYC-USERS</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.username</param-name>
+        <param-value>somenycuser</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.password</param-name>
+        <param-value>AReallyLoooongRandomPassword</param-value>
+    </init-param>
+</filter>
+
+<filter-mapping>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+</filter-mapping>
+
+ +The above will authenticate users accessing all content against the domain NYC-USERS. The WINS server 10.169.10.77 will be queried to resolve NYC-USERS to an IP address of a domain controller. If that WINS server is not responding, 10.169.10.66 will be queried. This example is suitable for large numbers of concurrent users because jCIFS will cycle through domain controllers and use an alternate WINS servers if necessary. In combination with the domain property, if a username and password are specified then preauthentication will be used. Preauthentication is necessary to initialize the SMB signing digest (see section on SMB signatures). + +

+Note: If you do not use WINS you must use the Explicit Domain Controller web.xml Example below or apply and use the DnsSrv.patch in the patches directory which uses JNDI to perform DNS SRV lookups for domain controllers. + +

Explicit Domain Controller web.xml Example

+ +The below example filter section illistrates how to specify a specific domain controller using the jcifs.http.domainController property. The domainContoller property supercedes the domain property when looking for a domain controller however it must still be specified if preauthentication is to be used for SMB signing. + +
+<filter>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <filter-class>jcifs.http.NtlmHttpFilter</filter-class>
+
+    <init-param>
+        <param-name>jcifs.http.domainController</param-name>
+        <param-value>192.168.2.15</param-value>
+    </init-param>
+
+    <!--
+        always needed for preauthentication / SMB signatures
+    -->
+    <init-param>
+        <param-name>jcifs.smb.client.domain</param-name>
+        <param-value>NYC-USERS</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.username</param-name>
+        <param-value>somenycuser</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.password</param-name>
+        <param-value>AReallyLoooongRandomPassword</param-value>
+    </init-param>
+</filter>
+
+<filter-mapping>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+</filter-mapping>
+
+ + +Note: This example will only work with with jcifs-1.2.8 or above. Prior to this version there was a logical bug in the preauthentication code that would cause signatures to fail resulting in repeated Access denied errors which in turn would cause the Network Password Dialog to appear regardless of what credentials were entered. + + +

Logon Share web.xml Example

+ +This example illustrates the jcifs.smb.client.logonShare property. This will cause jCIFS to attempt to access the resource \\192.168.2.15\JcifsAcl when authenticating users. By creating that share and changing the Access Control List only certain users or groups of users will have access to your website. + +
+<filter>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <filter-class>jcifs.http.NtlmHttpFilter</filter-class>
+
+    <init-param>
+        <param-name>jcifs.http.domainController</param-name>
+        <param-value>192.168.2.15</param-value>
+    </init-param>
+
+    <!--
+        permissions on \\192.168.2.15\JcifsAcl share gate web access
+    -->
+    <init-param>
+        <param-name>jcifs.smb.client.logonShare</param-name>
+        <param-value>JcifsAcl</param-value>
+    </init-param>
+
+    <!--
+        always needed for preauthentication / SMB signatures
+    -->
+    <init-param>
+        <param-name>jcifs.smb.client.domain</param-name>
+        <param-value>NYC-USERS</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.username</param-name>
+        <param-value>somenycuser</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.password</param-name>
+        <param-value>AReallyLoooongRandomPassword</param-value>
+    </init-param>
+</filter>
+
+<filter-mapping>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+</filter-mapping>
+
+ + +Note: Do not use a share that has files in it. JCIFS tries to list the contents of the share to determine if the user has access so it is more efficient if there's nothing in it. + + +Running the NtlmHttpAuthExample.java example should be a suitable test of the Filter. + +
+ +

NTLM HTTP Authentication Example

+NYC-USERS\MIALLEN successfully logged in +

Please submit some form data using POST

+ +
+ + + + +
+field1 = hello +
+ + +The significance of the POST test is that after negotiating NTLM HTTP Authentication once, IE will not POST any form data until it has negotiated the password hashes again (more about this below). + + +

+ +If the NTLM HTTP Authentication Filter is not enabled something like the following will be displayed: +
+null successfully logged in +
+ +Notice the user was permitted access. Unlike this example, developers might add an additional check to make sure getRemoteUser does not return null. + + + + +

Non MSIE Clients and "Basic" Authentication

+ +Both IE and FF can transparently negotiate NTLM HTTP authentication although IE needs the domain to be added to the IntrAnet security zone and FF requires configuration as described on the Integrated Authentication page. For other clients it is possible to use basic authentication to pass NTLM password credentials. This is strongly discouraged if SSL is not being used because it sends these credentials in plain text. It would not be difficult for another user to download and install a program to "snoop" LAN traffic and obtain other user's passwords. + +

+ +Regardless, this functionality has been added to the NtlmHttpFilter and NtlmServlet (for pre 2.3 servlet containers) although it is disabled by default. To enable this capability set the jcifs.http.basicRealm, jcifs.http.enableBasic, and jcifs.http.insecureBasic properties described in the table below. + + + + +

JCIFS Properties Meaningful to NTLM HTTP Authentication

+ +All parameters that begin with 'jcifs.' will be set as jCIFS properties which means that any jCIFS properties may be used as init parameters. These properties must be set before jCIFS classes are used. +For a complete list of jCIFS properties refer to the overview page of the API documentation. Here is a select subset of jCIFS properties with additional notes in the context of NTLM HTTP Authentication. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
jcifs.smb.client.domain +The NT domain against which clients should be authenticated. Generally it is necessary to also set the jcifs.netbios.wins parameter or a domain controller may not be found. This parameter will be ignored for NTLM HTTP authentication purposes if a jcifs.http.domainController property is specified (although they can be used together for "preauthenctication" as described in the SMB Signatures and Windows 2003 section below). +
jcifs.http.domainController +The IP address of any SMB server that should be used to authenticate HTTP clients with the NtlmHttpFilter class. If this is not specified the jcifs.smb.client.domain 0x1C NetBIOS group name will be queried. If these queries fail an UnknownHostException will be thrown. It is not necessary for this to specify a real domain controller. The IP address of a workstation will do for simple purposes. You can also use a DNS name however if you do this you should also set jcifs.resolveOrder=DNS. Otherwise, the client may waste time trying to resolve the name using WINS. +
jcifs.http.basicRealm +The realm for basic authentication. This property defaults to 'jCIFS'. +
jcifs.http.enableBasic +Setting this property to true enables basic authentication over HTTPS only. +
jcifs.http.insecureBasic +Setting this property to true enables basic authentication over plain HTTP. This configuration passes user credentials in plain text over the network. It should not be used in environment where security is required. +
jcifs.http.loadBalance +If a jcifs.smb.client.domain property is specified (and domainController is not specified) the NtlmHttpFilter will query for domain controllers by name. If this property is true the Filter will rotate through the list of domain controllers when authenticating users. The default value is true. The jcifs.netbios.lookupRespLimit property can also be used to limit the number of domain controllers used. +
jcifs.netbios.lookupRespLimit +The 0x1C NetBIOS name query returns a list of domain controllers. It is believed that the servers at the top of this list should be favored. This property limits the range of servers returned by name queries. The default value is 5 meaning the top 5 domain controllers will be used. +
jcifs.netbios.wins +The IP address of the WINS server. This is required when accessing hosts on different subnets (like a domain controller by name) and it is highly recommended if a wins server is available. +
jcifs.smb.client.laddr +The ip address of the local interface the client should bind to if it is different from the default. For example if jCIFS is used to authenticate clients on one interface and the domain controller for those clients is accessible only on another interface of a webserver with two NICs it may be necessary to specify which interface jCIFS should use. +
jcifs.netbios.laddr +The ip address of the local interface the client should bind to for name queries if it is different from the default. Likely set to the same as the above property. +
jcifs.smb.client.attrExpirationPeriod +Attributes of a file are cached for attrExpirationPeriod milliseconds. The default is 5000 but the NetworkExplorer servlet will attempt to set this property to 120000. Otherwise, when listing large directories, the attributes of SmbFiles may expire within the default period resulting in a large number of additional network messages and severe performance degradation. +
jcifs.smb.client.soTimeout +To prevent the client from holding server resources unnecessarily, sockets are closed after this time period if there is no activity. This time is specified in milliseconds. The default is 35000 however when NTLM HTTP Authentication is used, the NtlmHttpFilter will attempt to set this value to 5 minutes so that frequent calls to SmbSession.logon() do not provoke redundant messages being submitted to the domain controller. If it is not desirable to cache password hashes set this value back to 35000. +
jcifs.netbios.cachePolicy +When a NetBIOS name is resolved with the NbtAddress class it is cached to reduce redundant name queries. This property controls how long, in seconds, these names are cached. The default is 30 seconds, 0 is no caching, and -1 is forever. When NTLM HTTP Authentication is used, NtlmHttpFilter will attempt to set this value to 20 minutes so that frequent queries for a domain controller will be cached. +
jcifs.util.loglevel +A value that indicates the detail of logging messages. Values are approxamitly as follows: + + 0: Nothing + 1: Critical [default] + 2: Basic info. (Can be logged under load) + 3: Detailed info. (Highest recommended level for production use) + 4: Individual smb messages + 6: Hex dumps + +
+ + + + + +

Must Restart The Container

+ +If you change any jcifs properties or replace an existing jcifs jar file with a different one, the container must be restarted. This is because most jcifs properties are retrieved only once when classes are first loaded. + + + + +

Tomcat

+ +Tomcat may try to persist session objects when restarted. This can cause authentication failures if a user's creadentials are persisted because they will be invalid when deserialized. The solution is to either ask the affected user's to restart their browser or disable session persistance in part or in whole. The following will disable session persistence in Tomcat: + +
+<Context>
+...
+<Manager pathname=""/> <!-- disable session persistence -->
+</Context>
+
+ +Tomcat requires that all filter directives be adjacent to one another, all filter-mapping directives appear adjacent to one another, all servlet directives ... and so on. This is because Tomcat validates the web.xml against the deployment descriptor DTD (why the DTD would require such a thing I don't know). + + + + +

MalformedURLException: unknown protocol: smb

+ +If you get the following exception try upgrading to jcifs-0.7.0b12 or later. Also read the FAQ. +
+Exception MalformedURLException: unknown protocol: smb
+      at java.net.URL.(URL.java:480)
+      at java.net.URL.(URL.java:376)
+      at java.net.URL.(URL.java:330)
+      at jcifs.smb.SmbFile.(SmbFile.java:355)
+      ...
+
+ + + + + +

Transparent Authentication and the Network Password Dialog

+ +If the Filter is working properly the Network Password Dialog should never appear. However there are several requirements that must be met for a web browser to transparently negotiate credentials using NTLM HTTP authenication. If any of these requirements are not met, the default behavior is to present the user with the Network Password dialog. The requirements are: +

+ +
    + +
  1. +The client must be logged into the Windows NT domain identified by the jcifs.smb.client.domain parameter (or the domain of the host identified by the jcifs.smb.client.domainController parameter if it is used instead). The client may also be logged into a domain that has a trust relationship with the target domain. Indeed it is not uncommon to configure workstations to join a different domain from those of users. Note that Windows 95/98/ME systems cannot really join a domain but can be configured to do so enough to participate in transparent NTLM HTTP authentication. +
  2. +
  3. +By default, only Internet Explorer will negotiate NTLM HTTP authentication transparently. Mozilla must be configured to authenticate transparently. See these links for details: +

    + +http://kb.mozillazine.org/Network.automatic-ntlm-auth.trusted-uris +
    + +http://www.mozilla.org/projects/netlib/integrated-auth.html +
    + +

    + +
  4. +
  5. +Either the target URL must contain a server in the local domain (e.g. ws1.mycompany.com) or the client's security settings must be changed (e.g. Tools > Internet Options > Security > Local Intranet > Sites > Advanced > add your site). If the URL does not contain a URL in the defined IntrAnet zone (e.g. not an IP address), Internet Explorer will assume that the server is in the IntErnet zone and present the user with the Network Password dialog. It would be very bad if a server on the Internet could convince IE to send it your NTLM password hashes. These hashes are easily cracked with brute force dictionary attacks. To prevent this scenario, IE tries to distinguish between Intranet sites and Internet sites. Here are some important notes to consider when deploying a site with NTLM HTTP Authentication regardless of whether or not jCIFS is used to do it. + + +
  6. +
  7. +The user's credentials must be valid. For example if the account has expired, been disabled or is locked out the Network Password dialog will appear. To determine which error was at fault it will be necessary to modify the NtlmHttpFilter to inspect the SmbAuthException in doFilter. +
  8. +
  9. +The jCIFS client must support the lmCompatibility level necessary for communication with the domain controller. If the server does not permit NTLMv1 try to set jcifs.smb.lmCompatibility = 3. +
  10. + +
+ +Another reason for the Network Password Dialog appearing unexpectedly is if your web server has keep-alive turned off (e.g. KeepAlive directive in Apache http.conf). + + + +

Personal Workstation AD Security Policy

+ +If your Active Directory security policy requires that users only log into the domain from their +personal workstations JCIFS will fail to authenticate and the server security log will have entries like "\\JCIFS10_40_4A cannot be authorized". +This occurs because the domain controller is failing to resolve the dynamically generated "calling name" +submitted by the client during protocol negotiation. To get around this it is necessary to set the +jcifs.netbios.hostname property to a valid NetBIOS name that can be resolved by the NetBIOS name service (e.g. WINS) +and add that name to the AD security policy as a permitted client. +

+For example, you can set this property using an init-paremeter in the web.xml file for the NTLM HTTP filter as +follows: +
+<init-parameter>
+    <parameter-name>jcifs.netbios.hostname</parameter-name>
+    <parameter-value>MYHOSTNAME</parameter-value>
+</init-parameter>
+
+ + + + + +

HTTP POST and Protecting Sub-Content

+ +Once IE has negotiated NTLM HTTP authentication it will proactively renegotiate NTLM for POST requests for all content associated with the server (based on IP?). Therefore when using HTTP POST requests it is not possible to restrict access to some content on the server as IE will attempt and fail to negotiate NTLM (standard IE error page?). +

+Note that there is a registry key that will instruct IE to stop initiating NTLMSSP unless instructed by the server. + +
+ Type: DWORD
+  Key: HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Internet Settings/DisableNTLMPreAuth
+Value: 1
+
+ + + + +

SMB Signatures and Windows 2003

+ +If the domain controller against which you are authenticating clients requires SMB signatures (Windows 2003 does by default), it is recommended that you provide init-parameters for the jcifs.smb.client.{domain,username,password} properties to perform "preauthentication" for each transport to a domain contoller so that a proper SMB signing key can be generated. +

+An alternative solution is to change the +jcifs.smb.client.ssnLimit to 1. This will require that every +authentication uses a separate transport. Because the MAC signing key is +only used on SMB communication occuring after the initial authentication, +signing will be effectively ignored. However, this solution will +significantly reduce scalability as each authentication will open it's +own transport. For this reason preauthenticating transports is considered the superior method +and should be used by default for servers that requires signatures. + + + + +

NTLM HTTP Authentication Protocol Details

+ +The NTLM HTTP Authentication process is described well in these documents: +

+ +http://davenport.sourceforge.net/ntlm.html +
+ +http://www.innovation.ch/java/ntlm.html + +

+The process can be summarized as a 3 request/response "handshake". So doGet() will be called three times. The first is the initial request. A 401 Unauthorized is sent back to which IE submits a special message encoded in a header. Another 401 Unauthorized is sent back after which IE submits the password hashes. This is where jCIFS comes in. The password hashes alone are useless. You must check their authenticity against the password database on a server somewhere (actually you can specify the IP of a plain workstation or any other SMB server). Otherwise a user who's workstation is not a member of the domain will get a password dialog into which they could put anything and it would let them in. This is what pretty much all the examples seen in various forums do. Don't be fooled. +

+ +[1] Due to restrictions in how protocol handlers are loaded, if the SMB URL protocol handler is to be used (meaning you want to access SMB resources with smb:// URLs) within your application it is necessary for the jCIFS jar to be loaded by the System class loader. This can usually be achived by placing it in the container lib/ directory. However, for containers that load servlet classes in a child classloaders (Tomcat) this too will cause problems as jCIFS will not be able to load javax.servlet.* classes. To get the filter and the URL protocol handler to operate together requires some experimentation and depends on the container being used. + +
+ + Last updated June 1, 2009
jcifs-1.3.9
+ Copyright © 2004 The JCIFS Project
+validate this page
+ + diff --git a/docs/ntlmhttpauth.xml b/docs/ntlmhttpauth.xml new file mode 100644 index 0000000..657110a --- /dev/null +++ b/docs/ntlmhttpauth.xml @@ -0,0 +1,403 @@ + + + +JCIFS NTLM HTTP Authentication + + +IMPORTANT: All HTTP related code and corresponding documentation in JCIFS is not supported, no longer maintained and will be removed because it is broken and obsolete (and because HTTP has nothing to do with CIFS). This page remains only for informational purposes and for legacy users. +

+The HTTP "filter" in particular uses a "man in the middle" technique that cannot support NTLMv2. Since late 2008, users have started to report that client security policy is requiring NTLMv2 and that this solution no longer works. For this reason and others described in this post, this feature will be removed from the JCIFS package. +

+Currently we recommend using Jespa which properly implements NLTMv2 server side authentication and includes an advanced NTLMv2 HTTP SSO Servlet Filter. + +

+A common requirement of websites on corporate Intranets is NTLM HTTP authentication also sometimes referred to as Single Sign On (SSO). Microsoft Internet Explorer has the ability to negotiate NTLM password hashes over an HTTP session using base 64 encoded NTLMSSP messages. This is a staple feature of IIS but Java application servers too can use jCIFS to authenticate MSIE clients against a domain controller. This is a useful feature because many of the tasks surrounding user management now fall back to computer support and HR. It is not necessary to add and remove users as they join and leave the company. Perhaps most important from a user's perspective; they do not need to enter a username or password if their workstation is a member of the domain. The password hashes generated when they logged on to their workstation will be negotiated during the initial request for a session, passed through jCIFS, and validated against a PDC or BDC. This also makes the users domain and username available for managing session information, profiles, preferences, etc. Using the jCIFS Servlet Filter it is trivial to add NTLM HTTP authentication support to your site. It is also possible to build custom authentication modules using the NtlmSsp classes directly. This Filter scales very well primarily because sessions are multiplexed over transports. But this functionality is not without caveats. + +

+ +Note: This functionality is a non-conformant extension to HTTP conceived entirely by Microsoft. It inappropriately uses HTTP headers and therefore may not work with all Servlet containers or may stop working with a new release of your application server. Also, this flavor of password encryption is not very secure so under no circumstances should it be used to authenticate clients on the Internet. +

+Note: Don't forget to restart the container after changing jCIFS init-parameters. JCIFS must use the container class loader and jCIFS properties are only read once when jCIFS classes are initialized. + + +

Installation and Setup

+ +Put the latest jCIFS jar file in the lib/ directory of your webapp [1]. Because jCIFS properties are loaded once when the jCIFS classes are first accessed, it is necessary to actually stop and restart the container if any jCIFS properties have been changed. Create a filter section in your web.xml. Some example web.xml filter sections follow. + +

Production web.xml Example

+ +A minimalistic web.xml file with filter and filter-mapping directives might look like the following: + +
+<filter>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <filter-class>jcifs.http.NtlmHttpFilter</filter-class>
+
+    <init-param>
+        <param-name>jcifs.netbios.wins</param-name>
+        <param-value>10.169.10.77,10.169.10.66</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.domain</param-name>
+        <param-value>NYC-USERS</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.username</param-name>
+        <param-value>somenycuser</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.password</param-name>
+        <param-value>AReallyLoooongRandomPassword</param-value>
+    </init-param>
+</filter>
+
+<filter-mapping>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+</filter-mapping>
+
+ +The above will authenticate users accessing all content against the domain NYC-USERS. The WINS server 10.169.10.77 will be queried to resolve NYC-USERS to an IP address of a domain controller. If that WINS server is not responding, 10.169.10.66 will be queried. This example is suitable for large numbers of concurrent users because jCIFS will cycle through domain controllers and use an alternate WINS servers if necessary. In combination with the domain property, if a username and password are specified then preauthentication will be used. Preauthentication is necessary to initialize the SMB signing digest (see section on SMB signatures). + +

+Note: If you do not use WINS you must use the Explicit Domain Controller web.xml Example below or apply and use the DnsSrv.patch in the patches directory which uses JNDI to perform DNS SRV lookups for domain controllers. + +

Explicit Domain Controller web.xml Example

+ +The below example filter section illistrates how to specify a specific domain controller using the jcifs.http.domainController property. The domainContoller property supercedes the domain property when looking for a domain controller however it must still be specified if preauthentication is to be used for SMB signing. + +
+<filter>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <filter-class>jcifs.http.NtlmHttpFilter</filter-class>
+
+    <init-param>
+        <param-name>jcifs.http.domainController</param-name>
+        <param-value>192.168.2.15</param-value>
+    </init-param>
+
+    <!--
+        always needed for preauthentication / SMB signatures
+    -->
+    <init-param>
+        <param-name>jcifs.smb.client.domain</param-name>
+        <param-value>NYC-USERS</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.username</param-name>
+        <param-value>somenycuser</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.password</param-name>
+        <param-value>AReallyLoooongRandomPassword</param-value>
+    </init-param>
+</filter>
+
+<filter-mapping>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+</filter-mapping>
+
+ +Note: This example will only work with with jcifs-1.2.8 or above. Prior to this version there was a logical bug in the preauthentication code that would cause signatures to fail resulting in repeated Access denied errors which in turn would cause the Network Password Dialog to appear regardless of what credentials were entered. + +

Logon Share web.xml Example

+ +This example illustrates the jcifs.smb.client.logonShare property. This will cause jCIFS to attempt to access the resource \\192.168.2.15\JcifsAcl when authenticating users. By creating that share and changing the Access Control List only certain users or groups of users will have access to your website. + +
+<filter>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <filter-class>jcifs.http.NtlmHttpFilter</filter-class>
+
+    <init-param>
+        <param-name>jcifs.http.domainController</param-name>
+        <param-value>192.168.2.15</param-value>
+    </init-param>
+
+    <!--
+        permissions on \\192.168.2.15\JcifsAcl share gate web access
+    -->
+    <init-param>
+        <param-name>jcifs.smb.client.logonShare</param-name>
+        <param-value>JcifsAcl</param-value>
+    </init-param>
+
+    <!--
+        always needed for preauthentication / SMB signatures
+    -->
+    <init-param>
+        <param-name>jcifs.smb.client.domain</param-name>
+        <param-value>NYC-USERS</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.username</param-name>
+        <param-value>somenycuser</param-value>
+    </init-param>
+    <init-param>
+        <param-name>jcifs.smb.client.password</param-name>
+        <param-value>AReallyLoooongRandomPassword</param-value>
+    </init-param>
+</filter>
+
+<filter-mapping>
+    <filter-name>NtlmHttpFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+</filter-mapping>
+
+ +Note: Do not use a share that has files in it. JCIFS tries to list the contents of the share to determine if the user has access so it is more efficient if there's nothing in it. + + +Running the NtlmHttpAuthExample.java example should be a suitable test of the Filter. + +
+

NTLM HTTP Authentication Example

+NYC-USERS\MIALLEN successfully logged in +

Please submit some form data using POST

+
+ + +
+field1 = hello +
+ +The significance of the POST test is that after negotiating NTLM HTTP Authentication once, IE will not POST any form data until it has negotiated the password hashes again (more about this below). + +

+ +If the NTLM HTTP Authentication Filter is not enabled something like the following will be displayed: +

+null successfully logged in +
+ +Notice the user was permitted access. Unlike this example, developers might add an additional check to make sure getRemoteUser does not return null. + + + +

Non MSIE Clients and "Basic" Authentication

+ +Both IE and FF can transparently negotiate NTLM HTTP authentication although IE needs the domain to be added to the IntrAnet security zone and FF requires configuration as described on the
Integrated Authentication page. For other clients it is possible to use basic authentication to pass NTLM password credentials. This is strongly discouraged if SSL is not being used because it sends these credentials in plain text. It would not be difficult for another user to download and install a program to "snoop" LAN traffic and obtain other user's passwords. + +

+ +Regardless, this functionality has been added to the NtlmHttpFilter and NtlmServlet (for pre 2.3 servlet containers) although it is disabled by default. To enable this capability set the jcifs.http.basicRealm, jcifs.http.enableBasic, and jcifs.http.insecureBasic properties described in the table below. + + + +

JCIFS Properties Meaningful to NTLM HTTP Authentication

+ +All parameters that begin with 'jcifs.' will be set as jCIFS properties which means that any jCIFS properties may be used as init parameters. These properties must be set before jCIFS classes are used. +For a complete list of jCIFS properties refer to the overview page of the API documentation. Here is a select subset of jCIFS properties with additional notes in the context of NTLM HTTP Authentication. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
jcifs.smb.client.domain +The NT domain against which clients should be authenticated. Generally it is necessary to also set the jcifs.netbios.wins parameter or a domain controller may not be found. This parameter will be ignored for NTLM HTTP authentication purposes if a jcifs.http.domainController property is specified (although they can be used together for "preauthenctication" as described in the SMB Signatures and Windows 2003 section below). +
jcifs.http.domainController +The IP address of any SMB server that should be used to authenticate HTTP clients with the NtlmHttpFilter class. If this is not specified the jcifs.smb.client.domain 0x1C NetBIOS group name will be queried. If these queries fail an UnknownHostException will be thrown. It is not necessary for this to specify a real domain controller. The IP address of a workstation will do for simple purposes. You can also use a DNS name however if you do this you should also set jcifs.resolveOrder=DNS. Otherwise, the client may waste time trying to resolve the name using WINS. +
jcifs.http.basicRealm +The realm for basic authentication. This property defaults to 'jCIFS'. +
jcifs.http.enableBasic +Setting this property to true enables basic authentication over HTTPS only. +
jcifs.http.insecureBasic +Setting this property to true enables basic authentication over plain HTTP. This configuration passes user credentials in plain text over the network. It should not be used in environment where security is required. +
jcifs.http.loadBalance +If a jcifs.smb.client.domain property is specified (and domainController is not specified) the NtlmHttpFilter will query for domain controllers by name. If this property is true the Filter will rotate through the list of domain controllers when authenticating users. The default value is true. The jcifs.netbios.lookupRespLimit property can also be used to limit the number of domain controllers used. +
jcifs.netbios.lookupRespLimit +The 0x1C NetBIOS name query returns a list of domain controllers. It is believed that the servers at the top of this list should be favored. This property limits the range of servers returned by name queries. The default value is 5 meaning the top 5 domain controllers will be used. +
jcifs.netbios.wins +The IP address of the WINS server. This is required when accessing hosts on different subnets (like a domain controller by name) and it is highly recommended if a wins server is available. +
jcifs.smb.client.laddr +The ip address of the local interface the client should bind to if it is different from the default. For example if jCIFS is used to authenticate clients on one interface and the domain controller for those clients is accessible only on another interface of a webserver with two NICs it may be necessary to specify which interface jCIFS should use. +
jcifs.netbios.laddr +The ip address of the local interface the client should bind to for name queries if it is different from the default. Likely set to the same as the above property. +
jcifs.smb.client.attrExpirationPeriod +Attributes of a file are cached for attrExpirationPeriod milliseconds. The default is 5000 but the NetworkExplorer servlet will attempt to set this property to 120000. Otherwise, when listing large directories, the attributes of SmbFiles may expire within the default period resulting in a large number of additional network messages and severe performance degradation. +
jcifs.smb.client.soTimeout +To prevent the client from holding server resources unnecessarily, sockets are closed after this time period if there is no activity. This time is specified in milliseconds. The default is 35000 however when NTLM HTTP Authentication is used, the NtlmHttpFilter will attempt to set this value to 5 minutes so that frequent calls to SmbSession.logon() do not provoke redundant messages being submitted to the domain controller. If it is not desirable to cache password hashes set this value back to 35000. +
jcifs.netbios.cachePolicy +When a NetBIOS name is resolved with the NbtAddress class it is cached to reduce redundant name queries. This property controls how long, in seconds, these names are cached. The default is 30 seconds, 0 is no caching, and -1 is forever. When NTLM HTTP Authentication is used, NtlmHttpFilter will attempt to set this value to 20 minutes so that frequent queries for a domain controller will be cached. +
jcifs.util.loglevel +A value that indicates the detail of logging messages. Values are approxamitly as follows: + + 0: Nothing + 1: Critical [default] + 2: Basic info. (Can be logged under load) + 3: Detailed info. (Highest recommended level for production use) + 4: Individual smb messages + 6: Hex dumps + +
+ + + +

Must Restart The Container

+ +If you change any jcifs properties or replace an existing jcifs jar file with a different one, the container must be restarted. This is because most jcifs properties are retrieved only once when classes are first loaded. + + + +

Tomcat

+ +Tomcat may try to persist session objects when restarted. This can cause authentication failures if a user's creadentials are persisted because they will be invalid when deserialized. The solution is to either ask the affected user's to restart their browser or disable session persistance in part or in whole. The following will disable session persistence in Tomcat: + +
+<Context>
+...
+<Manager pathname=""/> <!-- disable session persistence -->
+</Context>
+
+ +Tomcat requires that all filter directives be adjacent to one another, all filter-mapping directives appear adjacent to one another, all servlet directives ... and so on. This is because Tomcat validates the web.xml against the deployment descriptor DTD (why the DTD would require such a thing I don't know). + + +
+

MalformedURLException: unknown protocol: smb

+ +If you get the following exception try upgrading to jcifs-0.7.0b12 or later. Also read the
FAQ. +
+Exception MalformedURLException: unknown protocol: smb
+      at java.net.URL.(URL.java:480)
+      at java.net.URL.(URL.java:376)
+      at java.net.URL.(URL.java:330)
+      at jcifs.smb.SmbFile.(SmbFile.java:355)
+      ...
+
+ + + +

Transparent Authentication and the Network Password Dialog

+ +If the Filter is working properly the Network Password Dialog should never appear. However there are several requirements that must be met for a web browser to transparently negotiate credentials using NTLM HTTP authenication. If any of these requirements are not met, the default behavior is to present the user with the Network Password dialog. The requirements are: +

+

    +
  1. +The client must be logged into the Windows NT domain identified by the jcifs.smb.client.domain parameter (or the domain of the host identified by the jcifs.smb.client.domainController parameter if it is used instead). The client may also be logged into a domain that has a trust relationship with the target domain. Indeed it is not uncommon to configure workstations to join a different domain from those of users. Note that Windows 95/98/ME systems cannot really join a domain but can be configured to do so enough to participate in transparent NTLM HTTP authentication. +
  2. +By default, only Internet Explorer will negotiate NTLM HTTP authentication transparently. Mozilla must be configured to authenticate transparently. See these links for details: +

    +http://kb.mozillazine.org/Network.automatic-ntlm-auth.trusted-uris
    +http://www.mozilla.org/projects/netlib/integrated-auth.html
    +

    +

  3. +Either the target URL must contain a server in the local domain (e.g. ws1.mycompany.com) or the client's security settings must be changed (e.g. Tools > Internet Options > Security > Local Intranet > Sites > Advanced > add your site). If the URL does not contain a URL in the defined IntrAnet zone (e.g. not an IP address), Internet Explorer will assume that the server is in the IntErnet zone and present the user with the Network Password dialog. It would be very bad if a server on the Internet could convince IE to send it your NTLM password hashes. These hashes are easily cracked with brute force dictionary attacks. To prevent this scenario, IE tries to distinguish between Intranet sites and Internet sites. Here are some important notes to consider when deploying a site with NTLM HTTP Authentication regardless of whether or not jCIFS is used to do it. + +
  4. +The user's credentials must be valid. For example if the account has expired, been disabled or is locked out the Network Password dialog will appear. To determine which error was at fault it will be necessary to modify the NtlmHttpFilter to inspect the SmbAuthException in doFilter. +
  5. +The jCIFS client must support the lmCompatibility level necessary for communication with the domain controller. If the server does not permit NTLMv1 try to set jcifs.smb.lmCompatibility = 3. +
  6. +
+ +Another reason for the Network Password Dialog appearing unexpectedly is if your web server has keep-alive turned off (e.g. KeepAlive directive in Apache http.conf). + + +

Personal Workstation AD Security Policy

+ +If your Active Directory security policy requires that users only log into the domain from their +personal workstations JCIFS will fail to authenticate and the server security log will have entries like "\\JCIFS10_40_4A cannot be authorized". +This occurs because the domain controller is failing to resolve the dynamically generated "calling name" +submitted by the client during protocol negotiation. To get around this it is necessary to set the +jcifs.netbios.hostname property to a valid NetBIOS name that can be resolved by the NetBIOS name service (e.g. WINS) +and add that name to the AD security policy as a permitted client. +

+For example, you can set this property using an init-paremeter in the web.xml file for the NTLM HTTP filter as +follows: +

+<init-parameter>
+    <parameter-name>jcifs.netbios.hostname</parameter-name>
+    <parameter-value>MYHOSTNAME</parameter-value>
+</init-parameter>
+
+ + +
+

HTTP POST and Protecting Sub-Content

+ +Once IE has negotiated NTLM HTTP authentication it will proactively renegotiate NTLM for POST requests for all content associated with the server (based on IP?). Therefore when using HTTP POST requests it is not possible to restrict access to some content on the server as IE will attempt and fail to negotiate NTLM (standard IE error page?). +

+Note that there is a registry key that will instruct IE to stop initiating NTLMSSP unless instructed by the server. + +

+ Type: DWORD
+  Key: HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Internet Settings/DisableNTLMPreAuth
+Value: 1
+
+ +
+

SMB Signatures and Windows 2003

+ +If the domain controller against which you are authenticating clients requires SMB signatures (Windows 2003 does by default), it is recommended that you provide init-parameters for the jcifs.smb.client.{domain,username,password} properties to perform "preauthentication" for each transport to a domain contoller so that a proper SMB signing key can be generated. +

+An alternative solution is to change the +jcifs.smb.client.ssnLimit to 1. This will require that every +authentication uses a separate transport. Because the MAC signing key is +only used on SMB communication occuring after the initial authentication, +signing will be effectively ignored. However, this solution will +significantly reduce scalability as each authentication will open it's +own transport. For this reason preauthenticating transports is considered the superior method +and should be used by default for servers that requires signatures. + + +
+

NTLM HTTP Authentication Protocol Details

+ +The NTLM HTTP Authentication process is described well in these documents: +

+http://davenport.sourceforge.net/ntlm.html
+http://www.innovation.ch/java/ntlm.html +

+The process can be summarized as a 3 request/response "handshake". So doGet() will be called three times. The first is the initial request. A 401 Unauthorized is sent back to which IE submits a special message encoded in a header. Another 401 Unauthorized is sent back after which IE submits the password hashes. This is where jCIFS comes in. The password hashes alone are useless. You must check their authenticity against the password database on a server somewhere (actually you can specify the IP of a plain workstation or any other SMB server). Otherwise a user who's workstation is not a member of the domain will get a password dialog into which they could put anything and it would let them in. This is what pretty much all the examples seen in various forums do. Don't be fooled. +

+[1] Due to restrictions in how protocol handlers are loaded, if the SMB URL protocol handler is to be used (meaning you want to access SMB resources with smb:// URLs) within your application it is necessary for the jCIFS jar to be loaded by the System class loader. This can usually be achived by placing it in the container lib/ directory. However, for containers that load servlet classes in a child classloaders (Tomcat) this too will cause problems as jCIFS will not be able to load javax.servlet.* classes. To get the filter and the URL protocol handler to operate together requires some experimentation and depends on the container being used. + diff --git a/docs/ntstatus.txt b/docs/ntstatus.txt new file mode 100644 index 0000000..f7e273d --- /dev/null +++ b/docs/ntstatus.txt @@ -0,0 +1,505 @@ +1 0x00000000 0x00000000 NT_STATUS_OK "The operation completed successfully." +1 0xC0000001 0x001f0001 NT_STATUS_UNSUCCESSFUL "A device attached to the system is not functioning." +1 0xC0000002 0x00010001 NT_STATUS_NOT_IMPLEMENTED "Incorrect function." +1 0xC0000003 0x00570001 NT_STATUS_INVALID_INFO_CLASS "The parameter is incorrect." +0 0xC0000004 0x00180001 NT_STATUS_INFO_LENGTH_MISMATCH "The program issued a command but the command length is incorrect." +1 0xC0000005 0x03e60001 NT_STATUS_ACCESS_VIOLATION "Invalid access to memory location." +0 0xC0000006 0x03e70001 NT_STATUS_IN_PAGE_ERROR "Error performing inpage operation." +0 0xC0000007 0x05ae0001 NT_STATUS_PAGEFILE_QUOTA "Insufficient quota to complete the requested service." +1 0xC0000008 0x00060001 NT_STATUS_INVALID_HANDLE "The handle is invalid." +0 0xC0000009 0x03e90001 NT_STATUS_BAD_INITIAL_STACK "Recursion too deep, stack overflowed." +0 0xC000000a 0x00c10001 NT_STATUS_BAD_INITIAL_PC "Not a valid Windows NT application." +0 0xC000000b 0x00570001 NT_STATUS_INVALID_CID "The parameter is incorrect." +0 0xC000000c 0x001f0003 NT_STATUS_TIMER_NOT_CANCELED "NT_STATUS_TIMER_NOT_CANCELED" +1 0xC000000d 0x00570001 NT_STATUS_INVALID_PARAMETER "The parameter is incorrect." +1 0xC000000e 0x00020001 NT_STATUS_NO_SUCH_DEVICE "The system cannot find the file specified." +1 0xC000000f 0x00020001 NT_STATUS_NO_SUCH_FILE "The system cannot find the file specified." +0 0xC0000010 0x00010001 NT_STATUS_INVALID_DEVICE_REQUEST "Incorrect function." +0 0xC0000011 0x00260001 NT_STATUS_END_OF_FILE "Reached end of file." +0 0xC0000012 0x00220001 NT_STATUS_WRONG_VOLUME "The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1." +0 0xC0000013 0x00150001 NT_STATUS_NO_MEDIA_IN_DEVICE "The device is not ready." +0 0xC0000014 0x06f90001 NT_STATUS_UNRECOGNIZED_MEDIA "The disk media is not recognized. It may not be formatted." +0 0xC0000015 0x001b0001 NT_STATUS_NONEXISTENT_SECTOR "The drive cannot find the sector requested." +1 0xC0000016 0x00ea0001 NT_STATUS_MORE_PROCESSING_REQUIRED "More data is available." +0 0xC0000017 0x00080001 NT_STATUS_NO_MEMORY "Not enough storage is available to process this command." +0 0xC0000018 0x01e70001 NT_STATUS_CONFLICTING_ADDRESSES "Attempt to access invalid address." +0 0xC0000019 0x01e70001 NT_STATUS_NOT_MAPPED_VIEW "Attempt to access invalid address." +0 0xC000001a 0x00570001 NT_STATUS_UNABLE_TO_FREE_VM "The parameter is incorrect." +0 0xC000001b 0x00570001 NT_STATUS_UNABLE_TO_DELETE_SECTION "The parameter is incorrect." +0 0xC000001c 0x00010001 NT_STATUS_INVALID_SYSTEM_SERVICE "Incorrect function." +0 0xC000001d 0x001d0001 NT_STATUS_ILLEGAL_INSTRUCTION "NT_STATUS_ILLEGAL_INSTRUCTION" +0 0xC000001e 0x00050001 NT_STATUS_INVALID_LOCK_SEQUENCE "Access is denied." +0 0xC000001f 0x00050001 NT_STATUS_INVALID_VIEW_SIZE "Access is denied." +0 0xC0000020 0x00c10001 NT_STATUS_INVALID_FILE_FOR_SECTION "Not a valid Windows NT application." +0 0xC0000021 0x00050001 NT_STATUS_ALREADY_COMMITTED "Access is denied." +1 0xC0000022 0x00050001 NT_STATUS_ACCESS_DENIED "Access is denied." +1 0xC0000023 0x007a0001 NT_STATUS_BUFFER_TOO_SMALL "The data area passed to a system call is too small." +0 0xC0000024 0x00060001 NT_STATUS_OBJECT_TYPE_MISMATCH "The handle is invalid." +0 0xC0000025 0x00250001 NT_STATUS_NONCONTINUABLE_EXCEPTION "NT_STATUS_NONCONTINUABLE_EXCEPTION" +0 0xC0000026 0x00260001 NT_STATUS_INVALID_DISPOSITION "NT_STATUS_INVALID_DISPOSITION" +0 0xC0000027 0x001f0003 NT_STATUS_UNWIND "NT_STATUS_UNWIND" +0 0xC0000028 0x001f0003 NT_STATUS_BAD_STACK "NT_STATUS_BAD_STACK" +0 0xC0000029 0x001f0003 NT_STATUS_INVALID_UNWIND_TARGET "NT_STATUS_INVALID_UNWIND_TARGET" +0 0xC000002a 0x009e0001 NT_STATUS_NOT_LOCKED "The segment is already unlocked." +0 0xC000002b 0x002b0001 NT_STATUS_PARITY_ERROR "NT_STATUS_PARITY_ERROR" +0 0xC000002c 0x01e70001 NT_STATUS_UNABLE_TO_DECOMMIT_VM "Attempt to access invalid address." +0 0xC000002d 0x01e70001 NT_STATUS_NOT_COMMITTED "Attempt to access invalid address." +0 0xC000002e 0x001f0003 NT_STATUS_INVALID_PORT_ATTRIBUTES "NT_STATUS_INVALID_PORT_ATTRIBUTES" +0 0xC000002f 0x001f0003 NT_STATUS_PORT_MESSAGE_TOO_LONG "NT_STATUS_PORT_MESSAGE_TOO_LONG" +0 0xC0000030 0x00570001 NT_STATUS_INVALID_PARAMETER_MIX "The parameter is incorrect." +0 0xC0000031 0x001f0003 NT_STATUS_INVALID_QUOTA_LOWER "NT_STATUS_INVALID_QUOTA_LOWER" +0 0xC0000032 0x05710001 NT_STATUS_DISK_CORRUPT_ERROR "The disk structure is corrupt and non-readable." +1 0xC0000033 0x007b0001 NT_STATUS_OBJECT_NAME_INVALID "The filename, directory name, or volume label syntax is incorrect." +1 0xC0000034 0x00020001 NT_STATUS_OBJECT_NAME_NOT_FOUND "The system cannot find the file specified." +1 0xC0000035 0x00b70001 NT_STATUS_OBJECT_NAME_COLLISION "Cannot create a file when that file already exists." +0 0xC0000036 0x001f0003 NT_STATUS_HANDLE_NOT_WAITABLE "NT_STATUS_HANDLE_NOT_WAITABLE" +1 0xC0000037 0x00060001 NT_STATUS_PORT_DISCONNECTED "The handle is invalid." +0 0xC0000038 0x001f0003 NT_STATUS_DEVICE_ALREADY_ATTACHED "NT_STATUS_DEVICE_ALREADY_ATTACHED" +1 0xC0000039 0x00a10001 NT_STATUS_OBJECT_PATH_INVALID "The specified path is invalid." +1 0xC000003a 0x00030001 NT_STATUS_OBJECT_PATH_NOT_FOUND "The system cannot find the path specified." +1 0xC000003b 0x00a10001 NT_STATUS_OBJECT_PATH_SYNTAX_BAD "The specified path is invalid." +0 0xC000003c 0x045d0001 NT_STATUS_DATA_OVERRUN "The request could not be performed because of an I/O device error." +0 0xC000003d 0x045d0001 NT_STATUS_DATA_LATE_ERROR "The request could not be performed because of an I/O device error." +0 0xC000003e 0x00170001 NT_STATUS_DATA_ERROR "Data error (cyclic redundancy check)" +0 0xC000003f 0x00170001 NT_STATUS_CRC_ERROR "Data error (cyclic redundancy check)" +0 0xC0000040 0x00080001 NT_STATUS_SECTION_TOO_BIG "Not enough storage is available to process this command." +0 0xC0000041 0x00050001 NT_STATUS_PORT_CONNECTION_REFUSED "Access is denied." +0 0xC0000042 0x00060001 NT_STATUS_INVALID_PORT_HANDLE "The handle is invalid." +1 0xC0000043 0x00200001 NT_STATUS_SHARING_VIOLATION "The process cannot access the file because it is being used by another process." +0 0xC0000044 0x07180001 NT_STATUS_QUOTA_EXCEEDED "Not enough quota is available to process this command." +0 0xC0000045 0x00570001 NT_STATUS_INVALID_PAGE_PROTECTION "The parameter is incorrect." +0 0xC0000046 0x01200001 NT_STATUS_MUTANT_NOT_OWNED "Attempt to release mutex not owned by caller." +0 0xC0000047 0x012a0001 NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED "Too many posts were made to a semaphore." +0 0xC0000048 0x00570001 NT_STATUS_PORT_ALREADY_SET "The parameter is incorrect." +0 0xC0000049 0x00570001 NT_STATUS_SECTION_NOT_IMAGE "The parameter is incorrect." +0 0xC000004a 0x009c0001 NT_STATUS_SUSPEND_COUNT_EXCEEDED "The recipient process has refused the signal." +0 0xC000004b 0x00050001 NT_STATUS_THREAD_IS_TERMINATING "Access is denied." +0 0xC000004c 0x00570001 NT_STATUS_BAD_WORKING_SET_LIMIT "The parameter is incorrect." +0 0xC000004d 0x00570001 NT_STATUS_INCOMPATIBLE_FILE_MAP "The parameter is incorrect." +0 0xC000004e 0x00570001 NT_STATUS_SECTION_PROTECTION "The parameter is incorrect." +0 0xC000004f 0x001f0003 NT_STATUS_EAS_NOT_SUPPORTED "NT_STATUS_EAS_NOT_SUPPORTED" +0 0xC0000050 0x00ff0001 NT_STATUS_EA_TOO_LARGE "The extended attributes are inconsistent." +0 0xC0000051 0x05700001 NT_STATUS_NONEXISTENT_EA_ENTRY "The file or directory is corrupt and non-readable." +0 0xC0000052 0x05700001 NT_STATUS_NO_EAS_ON_FILE "The file or directory is corrupt and non-readable." +0 0xC0000053 0x05700001 NT_STATUS_EA_CORRUPT_ERROR "The file or directory is corrupt and non-readable." +0 0xC0000054 0x00210001 NT_STATUS_FILE_LOCK_CONFLICT "The process cannot access the file because another process has locked a portion of the file." +0 0xC0000055 0x00210001 NT_STATUS_LOCK_NOT_GRANTED "The process cannot access the file because another process has locked a portion of the file." +1 0xC0000056 0x00050001 NT_STATUS_DELETE_PENDING "Access is denied." +0 0xC0000057 0x00320001 NT_STATUS_CTL_FILE_NOT_SUPPORTED "The network request is not supported." +0 0xC0000058 0x05190001 NT_STATUS_UNKNOWN_REVISION "The revision level is unknown." +0 0xC0000059 0x051a0001 NT_STATUS_REVISION_MISMATCH "Indicates two revision levels are incompatible." +0 0xC000005a 0x051b0001 NT_STATUS_INVALID_OWNER "This security ID may not be assigned as the owner of this object." +0 0xC000005b 0x051c0001 NT_STATUS_INVALID_PRIMARY_GROUP "This security ID may not be assigned as the primary group of an object." +0 0xC000005c 0x051d0001 NT_STATUS_NO_IMPERSONATION_TOKEN "An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client." +0 0xC000005d 0x051e0001 NT_STATUS_CANT_DISABLE_MANDATORY "The group may not be disabled." +1 0xC000005e 0x051f0001 NT_STATUS_NO_LOGON_SERVERS "There are currently no logon servers available to service the logon request." +0 0xC000005f 0x05200001 NT_STATUS_NO_SUCH_LOGON_SESSION "A specified logon session does not exist. It may already have been terminated." +0 0xC0000060 0x05210001 NT_STATUS_NO_SUCH_PRIVILEGE "A specified privilege does not exist." +0 0xC0000061 0x05220001 NT_STATUS_PRIVILEGE_NOT_HELD "A required privilege is not held by the client." +0 0xC0000062 0x05230001 NT_STATUS_INVALID_ACCOUNT_NAME "The name provided is not a properly formed account name." +1 0xC0000063 0x05240001 NT_STATUS_USER_EXISTS "The specified user already exists." +1 0xC0000064 0x05250001 NT_STATUS_NO_SUCH_USER "The specified user does not exist." +0 0xC0000065 0x05260001 NT_STATUS_GROUP_EXISTS "The specified group already exists." +0 0xC0000066 0x05270001 NT_STATUS_NO_SUCH_GROUP "The specified group does not exist." +0 0xC0000067 0x05280001 NT_STATUS_MEMBER_IN_GROUP "Either the specified user account is already a member of the specified group, or the specified group cannot be deleted because it contains a member." +0 0xC0000068 0x05290001 NT_STATUS_MEMBER_NOT_IN_GROUP "The specified user account is not a member of the specified group account." +0 0xC0000069 0x052a0001 NT_STATUS_LAST_ADMIN "The last remaining administration account cannot be disabled or deleted." +1 0xC000006a 0x00560001 NT_STATUS_WRONG_PASSWORD "The specified network password is not correct." +0 0xC000006b 0x052c0001 NT_STATUS_ILL_FORMED_PASSWORD "Unable to update the password. The value provided for the new password contains values that are not allowed in passwords." +0 0xC000006c 0x052d0001 NT_STATUS_PASSWORD_RESTRICTION "Unable to update the password because a password update rule has been violated." +1 0xC000006d 0x052e0001 NT_STATUS_LOGON_FAILURE "Logon failure: unknown user name or bad password." +1 0xC000006e 0x052f0001 NT_STATUS_ACCOUNT_RESTRICTION "Logon failure: user account restriction." +1 0xC000006f 0x05300001 NT_STATUS_INVALID_LOGON_HOURS "Logon failure: account logon time restriction violation." +1 0xC0000070 0x05310001 NT_STATUS_INVALID_WORKSTATION "Logon failure: user not allowed to log on to this computer." +1 0xC0000071 0x05320001 NT_STATUS_PASSWORD_EXPIRED "Logon failure: the specified account password has expired." +1 0xC0000072 0x05330001 NT_STATUS_ACCOUNT_DISABLED "Logon failure: account currently disabled." +1 0xC0000073 0x05340001 NT_STATUS_NONE_MAPPED "No mapping between account names and security IDs was done." +0 0xC0000074 0x05350001 NT_STATUS_TOO_MANY_LUIDS_REQUESTED "Too many local user identifiers (LUIDs) were requested at one time." +0 0xC0000075 0x05360001 NT_STATUS_LUIDS_EXHAUSTED "No more local user identifiers (LUIDs) are available." +0 0xC0000076 0x05370001 NT_STATUS_INVALID_SUB_AUTHORITY "The subauthority part of a security ID is invalid for this particular use." +0 0xC0000077 0x05380001 NT_STATUS_INVALID_ACL "The access control list (ACL) structure is invalid." +1 0xC0000078 0x05390001 NT_STATUS_INVALID_SID "The security ID structure is invalid." +0 0xC0000079 0x053a0001 NT_STATUS_INVALID_SECURITY_DESCR "The security descriptor structure is invalid." +0 0xC000007a 0x007f0001 NT_STATUS_PROCEDURE_NOT_FOUND "The specified procedure could not be found." +0 0xC000007b 0x00c10001 NT_STATUS_INVALID_IMAGE_FORMAT "%1 is not a valid Windows NT application." +0 0xC000007c 0x03f00001 NT_STATUS_NO_TOKEN "An attempt was made to reference a token that does not exist." +0 0xC000007d 0x053c0001 NT_STATUS_BAD_INHERITANCE_ACL "The inherited access control list (ACL) or access control entry (ACE) could not be built." +0 0xC000007e 0x009e0001 NT_STATUS_RANGE_NOT_LOCKED "The segment is already unlocked." +0 0xC000007f 0x00700001 NT_STATUS_DISK_FULL "There is not enough space on the disk." +0 0xC0000080 0x053d0001 NT_STATUS_SERVER_DISABLED "The server is currently disabled." +0 0xC0000081 0x053e0001 NT_STATUS_SERVER_NOT_DISABLED "The server is currently enabled." +0 0xC0000082 0x00440001 NT_STATUS_TOO_MANY_GUIDS_REQUESTED "The name limit for the local computer network adapter card was exceeded." +0 0xC0000083 0x01030001 NT_STATUS_GUIDS_EXHAUSTED "No more data is available." +0 0xC0000084 0x053f0001 NT_STATUS_INVALID_ID_AUTHORITY "The value provided was an invalid value for an identifier authority." +0 0xC0000085 0x01030001 NT_STATUS_AGENTS_EXHAUSTED "No more data is available." +0 0xC0000086 0x009a0001 NT_STATUS_INVALID_VOLUME_LABEL "The volume label you entered exceeds the label character limit of the target file system." +0 0xC0000087 0x000e0001 NT_STATUS_SECTION_NOT_EXTENDED "Not enough storage is available to complete this operation." +0 0xC0000088 0x01e70001 NT_STATUS_NOT_MAPPED_DATA "Attempt to access invalid address." +0 0xC0000089 0x07140001 NT_STATUS_RESOURCE_DATA_NOT_FOUND "The specified image file did not contain a resource section." +0 0xC000008a 0x07150001 NT_STATUS_RESOURCE_TYPE_NOT_FOUND "The specified resource type can not be found in the image file." +0 0xC000008b 0x07160001 NT_STATUS_RESOURCE_NAME_NOT_FOUND "The specified resource name can not be found in the image file." +0 0xC000008c 0x008c0001 NT_STATUS_ARRAY_BOUNDS_EXCEEDED "NT_STATUS_ARRAY_BOUNDS_EXCEEDED" +0 0xC000008d 0x008d0001 NT_STATUS_FLOAT_DENORMAL_OPERAND "NT_STATUS_FLOAT_DENORMAL_OPERAND" +0 0xC000008e 0x008e0001 NT_STATUS_FLOAT_DIVIDE_BY_ZERO "NT_STATUS_FLOAT_DIVIDE_BY_ZERO" +0 0xC000008f 0x008f0001 NT_STATUS_FLOAT_INEXACT_RESULT "NT_STATUS_FLOAT_INEXACT_RESULT" +0 0xC0000090 0x00900001 NT_STATUS_FLOAT_INVALID_OPERATION "NT_STATUS_FLOAT_INVALID_OPERATION" +0 0xC0000091 0x00910001 NT_STATUS_FLOAT_OVERFLOW "NT_STATUS_FLOAT_OVERFLOW" +0 0xC0000092 0x00920001 NT_STATUS_FLOAT_STACK_CHECK "NT_STATUS_FLOAT_STACK_CHECK" +0 0xC0000093 0x00930001 NT_STATUS_FLOAT_UNDERFLOW "NT_STATUS_FLOAT_UNDERFLOW" +0 0xC0000094 0x00940001 NT_STATUS_INTEGER_DIVIDE_BY_ZERO "NT_STATUS_INTEGER_DIVIDE_BY_ZERO" +0 0xC0000095 0x02160001 NT_STATUS_INTEGER_OVERFLOW "Arithmetic result exceeded 32 bits." +0 0xC0000096 0x00960001 NT_STATUS_PRIVILEGED_INSTRUCTION "NT_STATUS_PRIVILEGED_INSTRUCTION" +0 0xC0000097 0x00080001 NT_STATUS_TOO_MANY_PAGING_FILES "Not enough storage is available to process this command." +0 0xC0000098 0x03ee0001 NT_STATUS_FILE_INVALID "The volume for a file has been externally altered such that the opened file is no longer valid." +0 0xC0000099 0x05400001 NT_STATUS_ALLOTTED_SPACE_EXCEEDED "No more memory is available for security information updates." +0 0xC000009a 0x05aa0001 NT_STATUS_INSUFFICIENT_RESOURCES "Insufficient system resources exist to complete the requested service." +0 0xC000009b 0x00030001 NT_STATUS_DFS_EXIT_PATH_FOUND "The system cannot find the path specified." +0 0xC000009c 0x00170001 NT_STATUS_DEVICE_DATA_ERROR "Data error (cyclic redundancy check)" +0 0xC000009d 0x00150001 NT_STATUS_DEVICE_NOT_CONNECTED "The device is not ready." +0 0xC000009e 0x00150001 NT_STATUS_DEVICE_POWER_FAILURE "The device is not ready." +0 0xC000009f 0x01e70001 NT_STATUS_FREE_VM_NOT_AT_BASE "Attempt to access invalid address." +0 0xC00000a0 0x01e70001 NT_STATUS_MEMORY_NOT_ALLOCATED "Attempt to access invalid address." +0 0xC00000a1 0x05ad0001 NT_STATUS_WORKING_SET_QUOTA "Insufficient quota to complete the requested service." +0 0xC00000a2 0x00130001 NT_STATUS_MEDIA_WRITE_PROTECTED "The media is write protected." +0 0xC00000a3 0x00150001 NT_STATUS_DEVICE_NOT_READY "The device is not ready." +0 0xC00000a4 0x05410001 NT_STATUS_INVALID_GROUP_ATTRIBUTES "The specified attributes are invalid, or incompatible with the attributes for the group as a whole." +0 0xC00000a5 0x05420001 NT_STATUS_BAD_IMPERSONATION_LEVEL "Either a required impersonation level was not provided, or the provided impersonation level is invalid." +0 0xC00000a6 0x05430001 NT_STATUS_CANT_OPEN_ANONYMOUS "Cannot open an anonymous level security token." +0 0xC00000a7 0x05440001 NT_STATUS_BAD_VALIDATION_CLASS "The validation information class requested was invalid." +0 0xC00000a8 0x05450001 NT_STATUS_BAD_TOKEN_TYPE "The type of the token is inappropriate for its attempted use." +0 0xC00000a9 0x001f0003 NT_STATUS_BAD_MASTER_BOOT_RECORD "NT_STATUS_BAD_MASTER_BOOT_RECORD" +0 0xC00000aa 0x001f0003 NT_STATUS_INSTRUCTION_MISALIGNMENT "NT_STATUS_INSTRUCTION_MISALIGNMENT" +1 0xC00000ab 0x00e70001 NT_STATUS_INSTANCE_NOT_AVAILABLE "All pipe instances are busy." +1 0xC00000ac 0x00e70001 NT_STATUS_PIPE_NOT_AVAILABLE "All pipe instances are busy." +1 0xC00000ad 0x00e60001 NT_STATUS_INVALID_PIPE_STATE "The pipe state is invalid." +1 0xC00000ae 0x00e70001 NT_STATUS_PIPE_BUSY "All pipe instances are busy." +0 0xC00000af 0x00010001 NT_STATUS_ILLEGAL_FUNCTION "Incorrect function." +1 0xC00000b0 0x00e90001 NT_STATUS_PIPE_DISCONNECTED "No process is on the other end of the pipe." +1 0xC00000b1 0x00e80001 NT_STATUS_PIPE_CLOSING "The pipe is being closed." +0 0xC00000b2 0x02170001 NT_STATUS_PIPE_CONNECTED "There is a process on other end of the pipe." +1 0xC00000b3 0x02180001 NT_STATUS_PIPE_LISTENING "Waiting for a process to open the other end of the pipe." +0 0xC00000b4 0x00e60001 NT_STATUS_INVALID_READ_MODE "The pipe state is invalid." +0 0xC00000b5 0x00790001 NT_STATUS_IO_TIMEOUT "The semaphore timeout period has expired." +0 0xC00000b6 0x00260001 NT_STATUS_FILE_FORCED_CLOSED "Reached end of file." +0 0xC00000b7 0x001f0003 NT_STATUS_PROFILING_NOT_STARTED "NT_STATUS_PROFILING_NOT_STARTED" +0 0xC00000b8 0x001f0003 NT_STATUS_PROFILING_NOT_STOPPED "NT_STATUS_PROFILING_NOT_STOPPED" +0 0xC00000b9 0x001f0003 NT_STATUS_COULD_NOT_INTERPRET "NT_STATUS_COULD_NOT_INTERPRET" +1 0xC00000ba 0x00050001 NT_STATUS_FILE_IS_A_DIRECTORY "Access is denied." +0 0xC00000bb 0x00320001 NT_STATUS_NOT_SUPPORTED "The network request is not supported." +0 0xC00000bc 0x00330001 NT_STATUS_REMOTE_NOT_LISTENING "The remote computer is not available." +1 0xC00000bd 0x00340001 NT_STATUS_DUPLICATE_NAME "A duplicate name exists on the network." +0 0xC00000be 0x00350001 NT_STATUS_BAD_NETWORK_PATH "The network path was not found." +0 0xC00000bf 0x00360001 NT_STATUS_NETWORK_BUSY "The network is busy." +0 0xC00000c0 0x00370001 NT_STATUS_DEVICE_DOES_NOT_EXIST "The specified network resource or device is no longer available." +0 0xC00000c1 0x00380001 NT_STATUS_TOO_MANY_COMMANDS "The network BIOS command limit has been reached." +0 0xC00000c2 0x00390001 NT_STATUS_ADAPTER_HARDWARE_ERROR "A network adapter hardware error occurred." +0 0xC00000c3 0x003a0001 NT_STATUS_INVALID_NETWORK_RESPONSE "The specified server cannot perform the requested operation." +0 0xC00000c4 0x003b0001 NT_STATUS_UNEXPECTED_NETWORK_ERROR "An unexpected network error occurred." +0 0xC00000c5 0x003c0001 NT_STATUS_BAD_REMOTE_ADAPTER "The remote adapter is not compatible." +0 0xC00000c6 0x003d0001 NT_STATUS_PRINT_QUEUE_FULL "The printer queue is full." +0 0xC00000c7 0x003e0001 NT_STATUS_NO_SPOOL_SPACE "Space to store the file waiting to be printed is not available on the server." +0 0xC00000c8 0x003f0001 NT_STATUS_PRINT_CANCELLED "Your file waiting to be printed was deleted." +1 0xC00000c9 0x00400001 NT_STATUS_NETWORK_NAME_DELETED "The specified network name is no longer available." +1 0xC00000ca 0x00410001 NT_STATUS_NETWORK_ACCESS_DENIED "Network access is denied." +0 0xC00000cb 0x00420001 NT_STATUS_BAD_DEVICE_TYPE "The network resource type is not correct." +1 0xC00000cc 0x00430001 NT_STATUS_BAD_NETWORK_NAME "The network name cannot be found." +0 0xC00000cd 0x00440001 NT_STATUS_TOO_MANY_NAMES "The name limit for the local computer network adapter card was exceeded." +0 0xC00000ce 0x00450001 NT_STATUS_TOO_MANY_SESSIONS "The network BIOS session limit was exceeded." +0 0xC00000cf 0x00460001 NT_STATUS_SHARING_PAUSED "The remote server has been paused or is in the process of being started." +1 0xC00000d0 0x00470001 NT_STATUS_REQUEST_NOT_ACCEPTED "No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept." +0 0xC00000d1 0x00480001 NT_STATUS_REDIRECTOR_PAUSED "The specified printer or disk device has been paused." +0 0xC00000d2 0x00580001 NT_STATUS_NET_WRITE_FAULT "A write fault occurred on the network." +0 0xC00000d3 0x001f0003 NT_STATUS_PROFILING_AT_LIMIT "NT_STATUS_PROFILING_AT_LIMIT" +0 0xC00000d4 0x00110001 NT_STATUS_NOT_SAME_DEVICE "The system cannot move the file to a different disk drive." +0 0xC00000d5 0x001f0003 NT_STATUS_FILE_RENAMED "NT_STATUS_FILE_RENAMED" +0 0xC00000d6 0x00f00001 NT_STATUS_VIRTUAL_CIRCUIT_CLOSED "The session was cancelled." +0 0xC00000d7 0x05460001 NT_STATUS_NO_SECURITY_ON_OBJECT "Unable to perform a security operation on an object which has no associated security." +0 0xC00000d8 0x001f0003 NT_STATUS_CANT_WAIT "NT_STATUS_CANT_WAIT" +0 0xC00000d9 0x00e80001 NT_STATUS_PIPE_EMPTY "The pipe is being closed." +1 0xC00000da 0x05470001 NT_STATUS_CANT_ACCESS_DOMAIN_INFO "Indicates a Windows NT Server could not be contacted or that objects within the domain are protected such that necessary information could not be retrieved." +0 0xC00000db 0x001f0003 NT_STATUS_CANT_TERMINATE_SELF "NT_STATUS_CANT_TERMINATE_SELF" +0 0xC00000dc 0x05480001 NT_STATUS_INVALID_SERVER_STATE "The security account manager (SAM) or local security authority (LSA) server was in the wrong state to perform the security operation." +0 0xC00000dd 0x05490001 NT_STATUS_INVALID_DOMAIN_STATE "The domain was in the wrong state to perform the security operation." +0 0xC00000de 0x054a0001 NT_STATUS_INVALID_DOMAIN_ROLE "This operation is only allowed for the Primary Domain Controller of the domain." +1 0xC00000df 0x054b0001 NT_STATUS_NO_SUCH_DOMAIN "The specified domain did not exist." +0 0xC00000e0 0x054c0001 NT_STATUS_DOMAIN_EXISTS "The specified domain already exists." +0 0xC00000e1 0x054d0001 NT_STATUS_DOMAIN_LIMIT_EXCEEDED "An attempt was made to exceed the limit on the number of domains per server." +0 0xC00000e2 0x001f0003 NT_STATUS_OPLOCK_NOT_GRANTED "NT_STATUS_OPLOCK_NOT_GRANTED" +0 0xC00000e3 0x001f0003 NT_STATUS_INVALID_OPLOCK_PROTOCOL "NT_STATUS_INVALID_OPLOCK_PROTOCOL" +0 0xC00000e4 0x054e0001 NT_STATUS_INTERNAL_DB_CORRUPTION "Unable to complete the requested operation because of either a catastrophic media failure or a data structure corruption on the disk." +0 0xC00000e5 0x054f0001 NT_STATUS_INTERNAL_ERROR "The security account database contains an internal inconsistency." +0 0xC00000e6 0x05500001 NT_STATUS_GENERIC_NOT_MAPPED "Generic access types were contained in an access mask which should already be mapped to non-generic types." +0 0xC00000e7 0x05510001 NT_STATUS_BAD_DESCRIPTOR_FORMAT "A security descriptor is not in the right format (absolute or self-relative)." +0 0xC00000e8 0x06f80001 NT_STATUS_INVALID_USER_BUFFER "The supplied user buffer is not valid for the requested operation." +0 0xC00000e9 0x001f0003 NT_STATUS_UNEXPECTED_IO_ERROR "NT_STATUS_UNEXPECTED_IO_ERROR" +0 0xC00000ea 0x001f0003 NT_STATUS_UNEXPECTED_MM_CREATE_ERR "NT_STATUS_UNEXPECTED_MM_CREATE_ERR" +0 0xC00000eb 0x001f0003 NT_STATUS_UNEXPECTED_MM_MAP_ERROR "NT_STATUS_UNEXPECTED_MM_MAP_ERROR" +0 0xC00000ec 0x001f0003 NT_STATUS_UNEXPECTED_MM_EXTEND_ERR "NT_STATUS_UNEXPECTED_MM_EXTEND_ERR" +0 0xC00000ed 0x05520001 NT_STATUS_NOT_LOGON_PROCESS "The requested action is restricted for use by logon processes only. The calling process has not registered as a logon process." +0 0xC00000ee 0x05530001 NT_STATUS_LOGON_SESSION_EXISTS "Cannot start a new logon session with an ID that is already in use." +0 0xC00000ef 0x00570001 NT_STATUS_INVALID_PARAMETER_1 "The parameter is incorrect." +0 0xC00000f0 0x00570001 NT_STATUS_INVALID_PARAMETER_2 "The parameter is incorrect." +0 0xC00000f1 0x00570001 NT_STATUS_INVALID_PARAMETER_3 "The parameter is incorrect." +0 0xC00000f2 0x00570001 NT_STATUS_INVALID_PARAMETER_4 "The parameter is incorrect." +0 0xC00000f3 0x00570001 NT_STATUS_INVALID_PARAMETER_5 "The parameter is incorrect." +0 0xC00000f4 0x00570001 NT_STATUS_INVALID_PARAMETER_6 "The parameter is incorrect." +0 0xC00000f5 0x00570001 NT_STATUS_INVALID_PARAMETER_7 "The parameter is incorrect." +0 0xC00000f6 0x00570001 NT_STATUS_INVALID_PARAMETER_8 "The parameter is incorrect." +0 0xC00000f7 0x00570001 NT_STATUS_INVALID_PARAMETER_9 "The parameter is incorrect." +0 0xC00000f8 0x00570001 NT_STATUS_INVALID_PARAMETER_10 "The parameter is incorrect." +0 0xC00000f9 0x00570001 NT_STATUS_INVALID_PARAMETER_11 "The parameter is incorrect." +0 0xC00000fa 0x00570001 NT_STATUS_INVALID_PARAMETER_12 "The parameter is incorrect." +0 0xC00000fb 0x00030001 NT_STATUS_REDIRECTOR_NOT_STARTED "The system cannot find the path specified." +0 0xC00000fc 0x001f0003 NT_STATUS_REDIRECTOR_STARTED "NT_STATUS_REDIRECTOR_STARTED" +0 0xC00000fd 0x03e90001 NT_STATUS_STACK_OVERFLOW "Recursion too deep, stack overflowed." +0 0xC00000fe 0x05540001 NT_STATUS_NO_SUCH_PACKAGE "A specified authentication package is unknown." +0 0xC00000ff 0x001f0003 NT_STATUS_BAD_FUNCTION_TABLE "NT_STATUS_BAD_FUNCTION_TABLE" +0 0xC0000101 0x00910001 NT_STATUS_DIRECTORY_NOT_EMPTY "The directory is not empty." +0 0xC0000102 0x05700001 NT_STATUS_FILE_CORRUPT_ERROR "The file or directory is corrupt and non-readable." +1 0xC0000103 0x010b0001 NT_STATUS_NOT_A_DIRECTORY "The directory name is invalid." +0 0xC0000104 0x05550001 NT_STATUS_BAD_LOGON_SESSION_STATE "The logon session is not in a state that is consistent with the requested operation." +0 0xC0000105 0x05560001 NT_STATUS_LOGON_SESSION_COLLISION "The logon session ID is already in use." +0 0xC0000106 0x00ce0001 NT_STATUS_NAME_TOO_LONG "The filename or extension is too long." +0 0xC0000107 0x001f0003 NT_STATUS_FILES_OPEN "NT_STATUS_FILES_OPEN" +0 0xC0000108 0x09640001 NT_STATUS_CONNECTION_IN_USE "The device is being accessed by an active process." +0 0xC0000109 0x001f0003 NT_STATUS_MESSAGE_NOT_FOUND "NT_STATUS_MESSAGE_NOT_FOUND" +0 0xC000010a 0x00050001 NT_STATUS_PROCESS_IS_TERMINATING "Access is denied." +0 0xC000010b 0x05570001 NT_STATUS_INVALID_LOGON_TYPE "A logon request contained an invalid logon type value." +0 0xC000010c 0x001f0003 NT_STATUS_NO_GUID_TRANSLATION "NT_STATUS_NO_GUID_TRANSLATION" +0 0xC000010d 0x05580001 NT_STATUS_CANNOT_IMPERSONATE "Unable to impersonate via a named pipe until data has been read from that pipe." +0 0xC000010e 0x04200001 NT_STATUS_IMAGE_ALREADY_LOADED "An instance of the service is already running." +0 0xC000010f 0x001f0003 NT_STATUS_ABIOS_NOT_PRESENT "NT_STATUS_ABIOS_NOT_PRESENT" +0 0xC0000110 0x001f0003 NT_STATUS_ABIOS_LID_NOT_EXIST "NT_STATUS_ABIOS_LID_NOT_EXIST" +0 0xC0000111 0x001f0003 NT_STATUS_ABIOS_LID_ALREADY_OWNED "NT_STATUS_ABIOS_LID_ALREADY_OWNED" +0 0xC0000112 0x001f0003 NT_STATUS_ABIOS_NOT_LID_OWNER "NT_STATUS_ABIOS_NOT_LID_OWNER" +0 0xC0000113 0x001f0003 NT_STATUS_ABIOS_INVALID_COMMAND "NT_STATUS_ABIOS_INVALID_COMMAND" +0 0xC0000114 0x001f0003 NT_STATUS_ABIOS_INVALID_LID "NT_STATUS_ABIOS_INVALID_LID" +0 0xC0000115 0x001f0003 NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE "NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" +0 0xC0000116 0x001f0003 NT_STATUS_ABIOS_INVALID_SELECTOR "NT_STATUS_ABIOS_INVALID_SELECTOR" +0 0xC0000117 0x001f0003 NT_STATUS_NO_LDT "NT_STATUS_NO_LDT" +0 0xC0000118 0x001f0003 NT_STATUS_INVALID_LDT_SIZE "NT_STATUS_INVALID_LDT_SIZE" +0 0xC0000119 0x001f0003 NT_STATUS_INVALID_LDT_OFFSET "NT_STATUS_INVALID_LDT_OFFSET" +0 0xC000011a 0x001f0003 NT_STATUS_INVALID_LDT_DESCRIPTOR "NT_STATUS_INVALID_LDT_DESCRIPTOR" +0 0xC000011b 0x00c10001 NT_STATUS_INVALID_IMAGE_NE_FORMAT "%1 is not a valid Windows NT application." +0 0xC000011c 0x05590001 NT_STATUS_RXACT_INVALID_STATE "The transaction state of a Registry subtree is incompatible with the requested operation." +0 0xC000011d 0x055a0001 NT_STATUS_RXACT_COMMIT_FAILURE "An internal security database corruption has been encountered." +0 0xC000011e 0x03ee0001 NT_STATUS_MAPPED_FILE_SIZE_ZERO "The volume for a file has been externally altered such that the opened file is no longer valid." +0 0xC000011f 0x00040001 NT_STATUS_TOO_MANY_OPENED_FILES "The system cannot open the file." +0 0xC0000120 0x03e30001 NT_STATUS_CANCELLED "The I/O operation has been aborted because of either a thread exit or an application request." +1 0xC0000121 0x00050001 NT_STATUS_CANNOT_DELETE "Access is denied." +0 0xC0000122 0x04ba0001 NT_STATUS_INVALID_COMPUTER_NAME "The format of the specified computer name is invalid." +0 0xC0000123 0x00050001 NT_STATUS_FILE_DELETED "Access is denied." +0 0xC0000124 0x055b0001 NT_STATUS_SPECIAL_ACCOUNT "Cannot perform this operation on built-in accounts." +0 0xC0000125 0x055c0001 NT_STATUS_SPECIAL_GROUP "Cannot perform this operation on this built-in special group." +0 0xC0000126 0x055d0001 NT_STATUS_SPECIAL_USER "Cannot perform this operation on this built-in special user." +0 0xC0000127 0x055e0001 NT_STATUS_MEMBERS_PRIMARY_GROUP "The user cannot be removed from a group because the group is currently the user's primary group." +0 0xC0000128 0x00060001 NT_STATUS_FILE_CLOSED "The handle is invalid." +0 0xC0000129 0x001f0003 NT_STATUS_TOO_MANY_THREADS "NT_STATUS_TOO_MANY_THREADS" +0 0xC000012a 0x001f0003 NT_STATUS_THREAD_NOT_IN_PROCESS "NT_STATUS_THREAD_NOT_IN_PROCESS" +0 0xC000012b 0x055f0001 NT_STATUS_TOKEN_ALREADY_IN_USE "The token is already in use as a primary token." +0 0xC000012c 0x001f0003 NT_STATUS_PAGEFILE_QUOTA_EXCEEDED "NT_STATUS_PAGEFILE_QUOTA_EXCEEDED" +0 0xC000012d 0x05af0001 NT_STATUS_COMMITMENT_LIMIT "The paging file is too small for this operation to complete." +0 0xC000012e 0x00c10001 NT_STATUS_INVALID_IMAGE_LE_FORMAT "%1 is not a valid Windows NT application." +0 0xC000012f 0x00c10001 NT_STATUS_INVALID_IMAGE_NOT_MZ "%1 is not a valid Windows NT application." +0 0xC0000130 0x00c10001 NT_STATUS_INVALID_IMAGE_PROTECT "%1 is not a valid Windows NT application." +0 0xC0000131 0x00c10001 NT_STATUS_INVALID_IMAGE_WIN_16 "%1 is not a valid Windows NT application." +0 0xC0000132 0x001f0003 NT_STATUS_LOGON_SERVER_CONFLICT "NT_STATUS_LOGON_SERVER_CONFLICT" +0 0xC0000133 0x001f0003 NT_STATUS_TIME_DIFFERENCE_AT_DC "NT_STATUS_TIME_DIFFERENCE_AT_DC" +0 0xC0000134 0x001f0003 NT_STATUS_SYNCHRONIZATION_REQUIRED "NT_STATUS_SYNCHRONIZATION_REQUIRED" +0 0xC0000135 0x007e0001 NT_STATUS_DLL_NOT_FOUND "The specified module could not be found." +0 0xC0000136 0x001f0003 NT_STATUS_OPEN_FAILED "NT_STATUS_OPEN_FAILED" +0 0xC0000137 0x001f0003 NT_STATUS_IO_PRIVILEGE_FAILED "NT_STATUS_IO_PRIVILEGE_FAILED" +0 0xC0000138 0x00b60001 NT_STATUS_ORDINAL_NOT_FOUND "The operating system cannot run %1." +0 0xC0000139 0x007f0001 NT_STATUS_ENTRYPOINT_NOT_FOUND "The specified procedure could not be found." +0 0xC000013a 0x001f0003 NT_STATUS_CONTROL_C_EXIT "NT_STATUS_CONTROL_C_EXIT" +0 0xC000013b 0x00400001 NT_STATUS_LOCAL_DISCONNECT "The specified network name is no longer available." +0 0xC000013c 0x00400001 NT_STATUS_REMOTE_DISCONNECT "The specified network name is no longer available." +0 0xC000013d 0x00330001 NT_STATUS_REMOTE_RESOURCES "The remote computer is not available." +0 0xC000013e 0x003b0001 NT_STATUS_LINK_FAILED "An unexpected network error occurred." +0 0xC000013f 0x003b0001 NT_STATUS_LINK_TIMEOUT "An unexpected network error occurred." +0 0xC0000140 0x003b0001 NT_STATUS_INVALID_CONNECTION "An unexpected network error occurred." +0 0xC0000141 0x003b0001 NT_STATUS_INVALID_ADDRESS "An unexpected network error occurred." +0 0xC0000142 0x045a0001 NT_STATUS_DLL_INIT_FAILED "A dynamic link library (DLL) initialization routine failed." +0 0xC0000143 0x001f0003 NT_STATUS_MISSING_SYSTEMFILE "NT_STATUS_MISSING_SYSTEMFILE" +0 0xC0000144 0x001f0003 NT_STATUS_UNHANDLED_EXCEPTION "NT_STATUS_UNHANDLED_EXCEPTION" +0 0xC0000145 0x001f0003 NT_STATUS_APP_INIT_FAILURE "NT_STATUS_APP_INIT_FAILURE" +0 0xC0000146 0x001f0003 NT_STATUS_PAGEFILE_CREATE_FAILED "NT_STATUS_PAGEFILE_CREATE_FAILED" +0 0xC0000147 0x001f0003 NT_STATUS_NO_PAGEFILE "NT_STATUS_NO_PAGEFILE" +0 0xC0000148 0x007c0001 NT_STATUS_INVALID_LEVEL "The system call level is not correct." +0 0xC0000149 0x00560001 NT_STATUS_WRONG_PASSWORD_CORE "The specified network password is not correct." +0 0xC000014a 0x001f0003 NT_STATUS_ILLEGAL_FLOAT_CONTEXT "NT_STATUS_ILLEGAL_FLOAT_CONTEXT" +1 0xC000014b 0x006d0001 NT_STATUS_PIPE_BROKEN "The pipe has been ended." +0 0xC000014c 0x03f10001 NT_STATUS_REGISTRY_CORRUPT "The configuration registry database is corrupt." +0 0xC000014d 0x03f80001 NT_STATUS_REGISTRY_IO_FAILED "An I/O operation initiated by the Registry failed unrecoverably. The Registry could not read in, or write out, or flush, one of the files that contain the system's image of the Registry." +0 0xC000014e 0x001f0003 NT_STATUS_NO_EVENT_PAIR "NT_STATUS_NO_EVENT_PAIR" +0 0xC000014f 0x03ed0001 NT_STATUS_UNRECOGNIZED_VOLUME "The volume does not contain a recognized file system. Please make sure that all required file system drivers are loaded and that the volume is not corrupt." +0 0xC0000150 0x045e0001 NT_STATUS_SERIAL_NO_DEVICE_INITED "No serial device was successfully initialized. The serial driver will unload." +1 0xC0000151 0x05600001 NT_STATUS_NO_SUCH_ALIAS "The specified local group does not exist." +0 0xC0000152 0x05610001 NT_STATUS_MEMBER_NOT_IN_ALIAS "The specified account name is not a member of the local group." +0 0xC0000153 0x05620001 NT_STATUS_MEMBER_IN_ALIAS "The specified account name is already a member of the local group." +0 0xC0000154 0x05630001 NT_STATUS_ALIAS_EXISTS "The specified local group already exists." +0 0xC0000155 0x05640001 NT_STATUS_LOGON_NOT_GRANTED "Logon failure: the user has not been granted the requested logon type at this computer." +0 0xC0000156 0x05650001 NT_STATUS_TOO_MANY_SECRETS "The maximum number of secrets that may be stored in a single system has been exceeded." +0 0xC0000157 0x05660001 NT_STATUS_SECRET_TOO_LONG "The length of a secret exceeds the maximum length allowed." +0 0xC0000158 0x05670001 NT_STATUS_INTERNAL_DB_ERROR "The local security authority database contains an internal inconsistency." +0 0xC0000159 0x03ef0001 NT_STATUS_FULLSCREEN_MODE "The requested operation cannot be performed in full-screen mode." +0 0xC000015a 0x05680001 NT_STATUS_TOO_MANY_CONTEXT_IDS "During a logon attempt, the user's security context accumulated too many security IDs." +1 0xC000015b 0x05690001 NT_STATUS_LOGON_TYPE_NOT_GRANTED "Logon failure: the user has not been granted the requested logon type at this computer." +0 0xC000015c 0x03f90001 NT_STATUS_NOT_REGISTRY_FILE "The system has attempted to load or restore a file into the Registry, but the specified file is not in a Registry file format." +0 0xC000015d 0x056a0001 NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED "A cross-encrypted password is necessary to change a user password." +0 0xC000015e 0x001f0003 NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR "NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR" +0 0xC000015f 0x045d0001 NT_STATUS_FT_MISSING_MEMBER "The request could not be performed because of an I/O device error." +0 0xC0000160 0x001f0003 NT_STATUS_ILL_FORMED_SERVICE_ENTRY "NT_STATUS_ILL_FORMED_SERVICE_ENTRY" +0 0xC0000161 0x001f0003 NT_STATUS_ILLEGAL_CHARACTER "NT_STATUS_ILLEGAL_CHARACTER" +0 0xC0000162 0x04590001 NT_STATUS_UNMAPPABLE_CHARACTER "No mapping for the Unicode character exists in the target multi-byte code page." +0 0xC0000163 0x001f0003 NT_STATUS_UNDEFINED_CHARACTER "NT_STATUS_UNDEFINED_CHARACTER" +0 0xC0000164 0x001f0003 NT_STATUS_FLOPPY_VOLUME "NT_STATUS_FLOPPY_VOLUME" +0 0xC0000165 0x04620001 NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND "No ID address mark was found on the floppy disk." +0 0xC0000166 0x04630001 NT_STATUS_FLOPPY_WRONG_CYLINDER "Mismatch between the floppy disk sector ID field and the floppy disk controller track address." +0 0xC0000167 0x04640001 NT_STATUS_FLOPPY_UNKNOWN_ERROR "The floppy disk controller reported an error that is not recognized by the floppy disk driver." +0 0xC0000168 0x04650001 NT_STATUS_FLOPPY_BAD_REGISTERS "The floppy disk controller returned inconsistent results in its registers." +0 0xC0000169 0x04660001 NT_STATUS_DISK_RECALIBRATE_FAILED "While accessing the hard disk, a recalibrate operation failed, even after retries." +0 0xC000016a 0x04670001 NT_STATUS_DISK_OPERATION_FAILED "While accessing the hard disk, a disk operation failed even after retries." +0 0xC000016b 0x04680001 NT_STATUS_DISK_RESET_FAILED "While accessing the hard disk, a disk controller reset was needed, but even that failed." +0 0xC000016c 0x045f0001 NT_STATUS_SHARED_IRQ_BUSY "Unable to open a device that was sharing an interrupt request (IRQ) with other devices. At least one other device that uses that IRQ was already opened." +0 0xC000016d 0x045d0001 NT_STATUS_FT_ORPHANING "The request could not be performed because of an I/O device error." +0 0xC0000172 0x04510001 NT_STATUS_PARTITION_FAILURE "Tape could not be partitioned." +0 0xC0000173 0x04520001 NT_STATUS_INVALID_BLOCK_LENGTH "When accessing a new tape of a multivolume partition, the current blocksize is incorrect." +0 0xC0000174 0x04530001 NT_STATUS_DEVICE_NOT_PARTITIONED "Tape partition information could not be found when loading a tape." +0 0xC0000175 0x04540001 NT_STATUS_UNABLE_TO_LOCK_MEDIA "Unable to lock the media eject mechanism." +0 0xC0000176 0x04550001 NT_STATUS_UNABLE_TO_UNLOAD_MEDIA "Unable to unload the media." +0 0xC0000177 0x04690001 NT_STATUS_EOM_OVERFLOW "Physical end of tape encountered." +0 0xC0000178 0x04580001 NT_STATUS_NO_MEDIA "No media in drive." +0 0xC000017a 0x056b0001 NT_STATUS_NO_SUCH_MEMBER "A new member could not be added to a local group because the member does not exist." +0 0xC000017b 0x056c0001 NT_STATUS_INVALID_MEMBER "A new member could not be added to a local group because the member has the wrong account type." +0 0xC000017c 0x03fa0001 NT_STATUS_KEY_DELETED "Illegal operation attempted on a Registry key which has been marked for deletion." +0 0xC000017d 0x03fb0001 NT_STATUS_NO_LOG_SPACE "System could not allocate the required space in a Registry log." +0 0xC000017e 0x056d0001 NT_STATUS_TOO_MANY_SIDS "Too many security IDs have been specified." +0 0xC000017f 0x056e0001 NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED "A cross-encrypted password is necessary to change this user password." +0 0xC0000180 0x03fc0001 NT_STATUS_KEY_HAS_CHILDREN "Cannot create a symbolic link in a Registry key that already has subkeys or values." +0 0xC0000181 0x03fd0001 NT_STATUS_CHILD_MUST_BE_VOLATILE "Cannot create a stable subkey under a volatile parent key." +0 0xC0000182 0x00570001 NT_STATUS_DEVICE_CONFIGURATION_ERROR "The parameter is incorrect." +0 0xC0000183 0x045d0001 NT_STATUS_DRIVER_INTERNAL_ERROR "The request could not be performed because of an I/O device error." +0 0xC0000184 0x00160001 NT_STATUS_INVALID_DEVICE_STATE "The device does not recognize the command." +0 0xC0000185 0x045d0001 NT_STATUS_IO_DEVICE_ERROR "The request could not be performed because of an I/O device error." +0 0xC0000186 0x045d0001 NT_STATUS_DEVICE_PROTOCOL_ERROR "The request could not be performed because of an I/O device error." +0 0xC0000187 0x001f0003 NT_STATUS_BACKUP_CONTROLLER "NT_STATUS_BACKUP_CONTROLLER" +0 0xC0000188 0x05de0001 NT_STATUS_LOG_FILE_FULL "The event log file is full." +0 0xC0000189 0x00130001 NT_STATUS_TOO_LATE "The media is write protected." +0 0xC000018a 0x06fa0001 NT_STATUS_NO_TRUST_LSA_SECRET "The workstation does not have a trust secret." +0 0xC000018b 0x06fb0001 NT_STATUS_NO_TRUST_SAM_ACCOUNT "The SAM database on the Windows NT Server does not have a computer account for this workstation trust relationship." +1 0xC000018c 0x06fc0001 NT_STATUS_TRUSTED_DOMAIN_FAILURE "The trust relationship between the primary domain and the trusted domain failed." +0 0xC000018d 0x06fd0001 NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE "The trust relationship between this workstation and the primary domain failed." +0 0xC000018e 0x05dc0001 NT_STATUS_EVENTLOG_FILE_CORRUPT "The event log file is corrupt." +0 0xC000018f 0x05dd0001 NT_STATUS_EVENTLOG_CANT_START "No event log file could be opened, so the event logging service did not start." +0 0xC0000190 0x06fe0001 NT_STATUS_TRUST_FAILURE "The network logon failed." +0 0xC0000191 0x001f0003 NT_STATUS_MUTANT_LIMIT_EXCEEDED "NT_STATUS_MUTANT_LIMIT_EXCEEDED" +0 0xC0000192 0x07000001 NT_STATUS_NETLOGON_NOT_STARTED "An attempt was made to logon, but the network logon service was not started." +0 0xC0000193 0x07010001 NT_STATUS_ACCOUNT_EXPIRED "The user's account has expired." +0 0xC0000194 0x046b0001 NT_STATUS_POSSIBLE_DEADLOCK "A potential deadlock condition has been detected." +0 0xC0000195 0x04c30001 NT_STATUS_NETWORK_CREDENTIAL_CONFLICT "The credentials supplied conflict with an existing set of credentials." +0 0xC0000196 0x04c40001 NT_STATUS_REMOTE_SESSION_LIMIT "An attempt was made to establish a session to a network server, but there are already too many sessions established to that server." +0 0xC0000197 0x05df0001 NT_STATUS_EVENTLOG_FILE_CHANGED "The event log file has changed between reads." +0 0xC0000198 0x070f0001 NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT "The account used is an interdomain trust account. Use your global user account or local user account to access this server." +1 0xC0000199 0x07100001 NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT "The account used is a Computer Account. Use your global user account or local user account to access this server." +0 0xC000019a 0x07110001 NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT "The account used is an server trust account. Use your global user account or local user account to access this server." +0 0xC000019b 0x07120001 NT_STATUS_DOMAIN_TRUST_INCONSISTENT "The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain." +0 0xC000019c 0x001f0003 NT_STATUS_FS_DRIVER_REQUIRED "NT_STATUS_FS_DRIVER_REQUIRED" +0 0xC0000202 0x05720001 NT_STATUS_NO_USER_SESSION_KEY "There is no user session key for the specified logon session." +0 0xC0000203 0x003b0001 NT_STATUS_USER_SESSION_DELETED "An unexpected network error occurred." +0 0xC0000204 0x07170001 NT_STATUS_RESOURCE_LANG_NOT_FOUND "The specified resource language ID cannot be found in the image file." +0 0xC0000205 0x046a0001 NT_STATUS_INSUFF_SERVER_RESOURCES "Not enough server storage is available to process this command." +0 0xC0000206 0x06f80001 NT_STATUS_INVALID_BUFFER_SIZE "The supplied user buffer is not valid for the requested operation." +0 0xC0000207 0x04be0001 NT_STATUS_INVALID_ADDRESS_COMPONENT "The format of the specified network name is invalid." +0 0xC0000208 0x04be0001 NT_STATUS_INVALID_ADDRESS_WILDCARD "The format of the specified network name is invalid." +0 0xC0000209 0x00440001 NT_STATUS_TOO_MANY_ADDRESSES "The name limit for the local computer network adapter card was exceeded." +0 0xC000020a 0x00340001 NT_STATUS_ADDRESS_ALREADY_EXISTS "A duplicate name exists on the network." +0 0xC000020b 0x00400001 NT_STATUS_ADDRESS_CLOSED "The specified network name is no longer available." +0 0xC000020c 0x00400001 NT_STATUS_CONNECTION_DISCONNECTED "The specified network name is no longer available." +0 0xC000020d 0x00400001 NT_STATUS_CONNECTION_RESET "The specified network name is no longer available." +0 0xC000020e 0x00440001 NT_STATUS_TOO_MANY_NODES "The name limit for the local computer network adapter card was exceeded." +0 0xC000020f 0x003b0001 NT_STATUS_TRANSACTION_ABORTED "An unexpected network error occurred." +0 0xC0000210 0x003b0001 NT_STATUS_TRANSACTION_TIMED_OUT "An unexpected network error occurred." +0 0xC0000211 0x003b0001 NT_STATUS_TRANSACTION_NO_RELEASE "An unexpected network error occurred." +0 0xC0000212 0x003b0001 NT_STATUS_TRANSACTION_NO_MATCH "An unexpected network error occurred." +0 0xC0000213 0x003b0001 NT_STATUS_TRANSACTION_RESPONDED "An unexpected network error occurred." +0 0xC0000214 0x003b0001 NT_STATUS_TRANSACTION_INVALID_ID "An unexpected network error occurred." +0 0xC0000215 0x003b0001 NT_STATUS_TRANSACTION_INVALID_TYPE "An unexpected network error occurred." +0 0xC0000216 0x00320001 NT_STATUS_NOT_SERVER_SESSION "The network request is not supported." +0 0xC0000217 0x00320001 NT_STATUS_NOT_CLIENT_SESSION "The network request is not supported." +0 0xC0000218 0x001f0003 NT_STATUS_CANNOT_LOAD_REGISTRY_FILE "NT_STATUS_CANNOT_LOAD_REGISTRY_FILE" +0 0xC0000219 0x001f0003 NT_STATUS_DEBUG_ATTACH_FAILED "NT_STATUS_DEBUG_ATTACH_FAILED" +0 0xC000021a 0x001f0003 NT_STATUS_SYSTEM_PROCESS_TERMINATED "NT_STATUS_SYSTEM_PROCESS_TERMINATED" +0 0xC000021b 0x001f0003 NT_STATUS_DATA_NOT_ACCEPTED "NT_STATUS_DATA_NOT_ACCEPTED" +0 0xC000021c 0x17e60001 NT_STATUS_NO_BROWSER_SERVERS_FOUND "The list of servers for this workgroup is not currently available" +0 0xC000021d 0x001f0003 NT_STATUS_VDM_HARD_ERROR "NT_STATUS_VDM_HARD_ERROR" +0 0xC000021e 0x001f0003 NT_STATUS_DRIVER_CANCEL_TIMEOUT "NT_STATUS_DRIVER_CANCEL_TIMEOUT" +0 0xC000021f 0x001f0003 NT_STATUS_REPLY_MESSAGE_MISMATCH "NT_STATUS_REPLY_MESSAGE_MISMATCH" +0 0xC0000220 0x046c0001 NT_STATUS_MAPPED_ALIGNMENT "The base address or the file offset specified does not have the proper alignment." +0 0xC0000221 0x00c10001 NT_STATUS_IMAGE_CHECKSUM_MISMATCH "%1 is not a valid Windows NT application." +0 0xC0000222 0x001f0003 NT_STATUS_LOST_WRITEBEHIND_DATA "NT_STATUS_LOST_WRITEBEHIND_DATA" +0 0xC0000223 0x001f0003 NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID "NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID" +1 0xC0000224 0x07730001 NT_STATUS_PASSWORD_MUST_CHANGE "The user must change his password before he logs on the first time." +1 0xC0000225 0x001f0003 NT_STATUS_NOT_FOUND "NT_STATUS_NOT_FOUND" +0 0xC0000226 0x001f0003 NT_STATUS_NOT_TINY_STREAM "NT_STATUS_NOT_TINY_STREAM" +0 0xC0000227 0x001f0003 NT_STATUS_RECOVERY_FAILURE "NT_STATUS_RECOVERY_FAILURE" +0 0xC0000228 0x001f0003 NT_STATUS_STACK_OVERFLOW_READ "NT_STATUS_STACK_OVERFLOW_READ" +0 0xC0000229 0x001f0003 NT_STATUS_FAIL_CHECK "NT_STATUS_FAIL_CHECK" +0 0xC000022a 0x022a0001 NT_STATUS_DUPLICATE_OBJECTID "NT_STATUS_DUPLICATE_OBJECTID" +0 0xC000022b 0x022b0001 NT_STATUS_OBJECTID_EXISTS "NT_STATUS_OBJECTID_EXISTS" +0 0xC000022c 0x001f0003 NT_STATUS_CONVERT_TO_LARGE "NT_STATUS_CONVERT_TO_LARGE" +0 0xC000022d 0x001f0003 NT_STATUS_RETRY "NT_STATUS_RETRY" +0 0xC000022e 0x001f0003 NT_STATUS_FOUND_OUT_OF_SCOPE "NT_STATUS_FOUND_OUT_OF_SCOPE" +0 0xC000022f 0x001f0003 NT_STATUS_ALLOCATE_BUCKET "NT_STATUS_ALLOCATE_BUCKET" +0 0xC0000230 0x001f0003 NT_STATUS_PROPSET_NOT_FOUND "NT_STATUS_PROPSET_NOT_FOUND" +0 0xC0000231 0x001f0003 NT_STATUS_MARSHALL_OVERFLOW "NT_STATUS_MARSHALL_OVERFLOW" +0 0xC0000232 0x001f0003 NT_STATUS_INVALID_VARIANT "NT_STATUS_INVALID_VARIANT" +0 0xC0000233 0x07740001 NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND "Could not find the domain controller for this domain." +1 0xC0000234 0x07750001 NT_STATUS_ACCOUNT_LOCKED_OUT "The referenced account is currently locked out and may not be logged on to." +0 0xC0000235 0x00060001 NT_STATUS_HANDLE_NOT_CLOSABLE "The handle is invalid." +0 0xC0000236 0x04c90001 NT_STATUS_CONNECTION_REFUSED "The remote system refused the network connection." +0 0xC0000237 0x04ca0001 NT_STATUS_GRACEFUL_DISCONNECT "The network connection was gracefully closed." +0 0xC0000238 0x04cb0001 NT_STATUS_ADDRESS_ALREADY_ASSOCIATED "The network transport endpoint already has an address associated with it." +0 0xC0000239 0x04cc0001 NT_STATUS_ADDRESS_NOT_ASSOCIATED "An address has not yet been associated with the network endpoint." +0 0xC000023a 0x04cd0001 NT_STATUS_CONNECTION_INVALID "An operation was attempted on a non-existent network connection." +0 0xC000023b 0x04ce0001 NT_STATUS_CONNECTION_ACTIVE "An invalid operation was attempted on an active network connection." +0 0xC000023c 0x04cf0001 NT_STATUS_NETWORK_UNREACHABLE "The remote network is not reachable by the transport." +0 0xC000023d 0x04d00001 NT_STATUS_HOST_UNREACHABLE "The remote system is not reachable by the transport." +0 0xC000023e 0x04d10001 NT_STATUS_PROTOCOL_UNREACHABLE "The remote system does not support the transport protocol." +0 0xC000023f 0x04d20001 NT_STATUS_PORT_UNREACHABLE "No service is operating at the destination network endpoint on the remote system." +0 0xC0000240 0x04d30001 NT_STATUS_REQUEST_ABORTED "The request was aborted." +0 0xC0000241 0x04d40001 NT_STATUS_CONNECTION_ABORTED "The network connection was aborted by the local system." +0 0xC0000242 0x001f0003 NT_STATUS_BAD_COMPRESSION_BUFFER "NT_STATUS_BAD_COMPRESSION_BUFFER" +0 0xC0000243 0x04c80001 NT_STATUS_USER_MAPPED_FILE "The requested operation cannot be performed on a file with a user mapped section open." +0 0xC0000244 0x001f0003 NT_STATUS_AUDIT_FAILED "NT_STATUS_AUDIT_FAILED" +0 0xC0000245 0x001f0003 NT_STATUS_TIMER_RESOLUTION_NOT_SET "NT_STATUS_TIMER_RESOLUTION_NOT_SET" +0 0xC0000246 0x04d60001 NT_STATUS_CONNECTION_COUNT_LIMIT "A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached." +0 0xC0000247 0x04d70001 NT_STATUS_LOGIN_TIME_RESTRICTION "Attempting to login during an unauthorized time of day for this account." +0 0xC0000248 0x04d80001 NT_STATUS_LOGIN_WKSTA_RESTRICTION "The account is not authorized to login from this station." +0 0xC0000249 0x00c10001 NT_STATUS_IMAGE_MP_UP_MISMATCH "%1 is not a valid Windows NT application." +0 0xC0000250 0x001f0003 NT_STATUS_INSUFFICIENT_LOGON_INFO "NT_STATUS_INSUFFICIENT_LOGON_INFO" +0 0xC0000251 0x001f0003 NT_STATUS_BAD_DLL_ENTRYPOINT "NT_STATUS_BAD_DLL_ENTRYPOINT" +0 0xC0000252 0x001f0003 NT_STATUS_BAD_SERVICE_ENTRYPOINT "NT_STATUS_BAD_SERVICE_ENTRYPOINT" +0 0xC0000253 0x054f0001 NT_STATUS_LPC_REPLY_LOST "The security account database contains an internal inconsistency." +0 0xC0000254 0x001f0003 NT_STATUS_IP_ADDRESS_CONFLICT1 "NT_STATUS_IP_ADDRESS_CONFLICT1" +0 0xC0000255 0x001f0003 NT_STATUS_IP_ADDRESS_CONFLICT2 "NT_STATUS_IP_ADDRESS_CONFLICT2" +0 0xC0000256 0x001f0003 NT_STATUS_REGISTRY_QUOTA_LIMIT "NT_STATUS_REGISTRY_QUOTA_LIMIT" +1 0xC0000257 0x04d00001 NT_STATUS_PATH_NOT_COVERED "The remote system is not reachable by the transport." +0 0xC0000258 0x001f0003 NT_STATUS_NO_CALLBACK_ACTIVE "NT_STATUS_NO_CALLBACK_ACTIVE" +0 0xC0000259 0x05730001 NT_STATUS_LICENSE_QUOTA_EXCEEDED "The service being accessed is licensed for a particular number of connections. No more connections can be made to the service at this time because there are already as many connections as the service can accept." +0 0xC000025a 0x001f0003 NT_STATUS_PWD_TOO_SHORT "NT_STATUS_PWD_TOO_SHORT" +0 0xC000025b 0x001f0003 NT_STATUS_PWD_TOO_RECENT "NT_STATUS_PWD_TOO_RECENT" +0 0xC000025c 0x001f0003 NT_STATUS_PWD_HISTORY_CONFLICT "NT_STATUS_PWD_HISTORY_CONFLICT" +0 0xC000025e 0x04220001 NT_STATUS_PLUGPLAY_NO_DEVICE "The specified service is disabled and cannot be started." +0 0xC000025f 0x001f0003 NT_STATUS_UNSUPPORTED_COMPRESSION "NT_STATUS_UNSUPPORTED_COMPRESSION" +0 0xC0000260 0x001f0003 NT_STATUS_INVALID_HW_PROFILE "NT_STATUS_INVALID_HW_PROFILE" +0 0xC0000261 0x001f0003 NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH "NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH" +0 0xC0000262 0x00b60001 NT_STATUS_DRIVER_ORDINAL_NOT_FOUND "The operating system cannot run %1." +0 0xC0000263 0x007f0001 NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND "The specified procedure could not be found." +0 0xC0000264 0x01200001 NT_STATUS_RESOURCE_NOT_OWNED "Attempt to release mutex not owned by caller." +0 0xC0000265 0x04760001 NT_STATUS_TOO_MANY_LINKS "An attempt was made to create more links on a file than the file system supports." +0 0xC0000266 0x001f0003 NT_STATUS_QUOTA_LIST_INCONSISTENT "NT_STATUS_QUOTA_LIST_INCONSISTENT" +0 0xC0000267 0x001f0003 NT_STATUS_FILE_IS_OFFLINE "NT_STATUS_FILE_IS_OFFLINE" +0 0xC0000275 0x001f0003 NT_STATUS_NOT_A_REPARSE_POINT "NT_STATUS_NOT_A_REPARSE_POINT" +1 0xC0000279 0x001f0003 NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED "NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED" +0 0xC0000EDE 0x001f0003 NT_STATUS_NO_SUCH_JOB "NT_STATUS_NO_SUCH_JOB" diff --git a/docs/overview.html b/docs/overview.html new file mode 100644 index 0000000..d03492d --- /dev/null +++ b/docs/overview.html @@ -0,0 +1,362 @@ +JCIFS Properties + +

+

JCIFS
+The Java CIFS Client Library

+http://jcifs.samba.org/
+

+ +

The JCIFS SMB client library enables Java applications to remotely +access shared files and directories on SMB file servers(i.e. +a Microsoft Windows "share") in addition to domain, workgroup, and +server enumeration of NetBIOS over TCP/IP networks. It is an advanced +implementation of the CIFS protocol supporting Unicode, batching, +multiplexing of threaded callers, encrypted authentication, transactions, +the Remote Access Protocol (RAP), and much more. It is licensed under +LGPL which means commercial organizations can legitimately use it with +their proprietary code(you just can't sell or give away a modified binary +only version of the library itself without reciprocation). + +

The API
+ +

The {@link jcifs.smb.SmbFile}, {@link jcifs.smb.SmbFileInputStream} +, and {@link jcifs.smb.SmbFileOutputStream} classes are analogous +to the {@link java.io.File}, {@link java.io.FileInputStream}, and +{@link java.io.FileOutputStream} classes so if you know how to use +those it should be quite obvious how to use jCIFS provided you set any +necessary properties (i.e. a WINS server) and understand the +smb:// URL syntax. + +

Here's an example to retrieve a file: + +

+import jcifs.smb.*;
+
+jcifs.Config.setProperty( "jcifs.netbios.wins", "192.168.1.220" );
+NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domain", "username", "password");
+SmbFileInputStream in = new SmbFileInputStream("smb://host/c/My Documents/somefile.txt", auth);
+byte[] b = new byte[8192];
+int n;
+while(( n = in.read( b )) > 0 ) {
+    System.out.write( b, 0, n );
+}
+
+ +

You can also read/write, delete, make directories, rename, list +contents of a directory, list the workgroups/ntdomains and servers on +the network, list the shares of a server, open named pipes, authenticate +web clients ...etc. + + +

+Setting Client Properties
+ +

It may be necessary to set various properties for the client to +function properly. For example, to connect to a server on a remote +subnet the IP address of a WINS server is +required to retrieve the target address although DNS names and direct +IP addresses are also valid server components within an SMB URL. + +

There are three ways to specify any of the available properties listed +the table at the bottom of this page. + +

    +
  • The traditional System properties are read when the client is first +used. This means you can specify an individual property (the full property +name) on the command line like: + +

    +$ java -Djcifs.netbios.wins=192.168.1.220 MyApp
    +
    + +

    OR set a System property from within your application before +any jCIFS classes are instantiated like: + +

    +System.setProperty( "jcifs.netbios.wins", "192.168.1.220" );
    +
    + +
  • OR use the jcifs.Config class which is the class that +maintains this information internally however, again, properties must +be set before jCIFS client classes are referenced: + +

    +jcifs.Config.setProperty( "jcifs.netbios.wins", "192.168.1.220" );
    +
    + +
  • OR if the property "jcifs.properties" defines the location of a properties file, all properties will be loaded from it. For example: + +

    +$ cat miallen.prp
    +jcifs.netbios.wins=192.168.1.220
    +jcifs.smb.client.username=miallen
    +jcifs.smb.client.password=legos56
    +;jcifs.netbios.baddr=192.168.1.255
    +;jcifs.util.loglevel = 10
    +$ java -Djcifs.properties=miallen.prp MyApp
    +
    + +
+ +

Any properties specified using the -Djcifs.properties=myjcifsproperties.prp file may be overridden using the System properties as will any -Dfull.property.name=value VM parameters which in turn may then be overridden by the direct manipulation of properties using the Config class. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Available Properties
+These properties may need to be specified for correct operation
jcifs.smb.client.username +The default username used if not specified in an SMB URL +
jcifs.smb.client.password +The default password used if not specified in an SMB URL +
jcifs.smb.client.domain +The default authentication domain used if not specified in an SMB URL +
jcifs.netbios.wins +The IP address of the WINS server. This is only required when accessing hosts on different subnets although it is recomended if a WINS server is provided. +
jcifs.netbios.baddr +The local network's broadcast address. It may be necessary to set this for certain network configurations because the default of 255.255.255.255 may otherwise throw a "Network is unreachable" IOException. For example if the local host's IP address is 192.168.1.15, the broadcast address would likely be 192.168.1.255. +
jcifs.netbios.scope +This is extremely rare but NetBIOS provides for a "scope id" to be used in a attempt to conceal groups of machines on the same network. Ask your network administrator if scope id is used. If so, it must be set using this property or name queries will fail. +
jcifs.smb.client.laddr +The IP address of the local interface the client should bind to if it is different from the default. For example if the client is to be used over a dial-up connection the IP address of the PPP interface may need to be specified with this property. +
jcifs.netbios.laddr +The IP address of the local interface the client should bind to for name queries if it is different from the default. +
jcifs.netbios.lmhosts +The path to an lmhosts file containing a map of IP addresses to hostnames. The format of this file is identical to that of the Windows lmhosts file format. +See Setting Name Resoultion Properties for details. +
jcifs.smb.client.disablePlainTextPasswords +Plain text passwords should never be used and are disabled by default. To enable jCIFS to use plain text password this property must be set to false. +
jcifs.encoding +If the locale character encoding of the target server is not MS-DOS Latin-1, this property needs to be changed to reflect the proper encoding (e.g. Cp866 for Russian). Otherwise, share names, passwords, and in some cases file and directory names that contain non ASCII characters may not be handled properly. See this list of Supported Encodings and concentrate on the ones attributed as MS-DOS encodings. By default this property is Cp860 which is MS-DOS Latin1. +

+Note: The Cp860 charset converter is located in jre/lib/charsets.jar which AFAIK is only supported by the internationalized version of Sun's JRE. If Cp860 is not available an exception will occur. To avoid this exception you can set jcifs.encoding to ASCII but share names and passwords with non-ASCII characters will not be processed correctly. To determine if jCIFS is properly processing these characters create a share that contains non-ASCII characers (e.g. Grüße) and then try to list that share with the ListFiles.java example program. +

+As of jcifs-1.2.8 this property no longer defaults to the file.encoding system property because it was almost always meaningless (e.g. usually it's UTF-8 on Linux and no CIFS server currently emits UTF-8). +

jcifs.smb.client.useExtendedSecurityTrue by default but this must be set to false for Samba 3.0.x as it seems older versions of Samba do not support *raw* NTLMSSP and currently JCIFS does not support SPNEGO.
Less Commonly Used Properties
+These properties are not required for the client to function but may be necessary for optimal utility
jcifs.resolveOrder +A comma separated list of name resolution method identifiers that specify which methods will be used and in what order to resolve hostnames. The possible identifiers in default order are LMHOSTS, WINS, BCAST, and DNS. +See Setting Name Resoultion Properties for details. +
jcifs.util.loglevel +An integer specifying the verbosity of log messages. Higher values are more verbose +
    +
  • 0 - No log messages are printed -- not even crticial exceptions.
  • +
  • 1 - The default level. Only critical messages are logged.
  • +
  • 2 - Hightened log messages suitable for logging while under load.
  • +
  • 3 - Almost everything.
  • +
  • N - Debugging only.
  • +
+
jcifs.util.log +Removed This property has been replaced by the above jcifs.util.loglevel property. +A series of string identifiers to induce log messages to be printed to the console such as log=EXC,DEB,WAR,HEX would log internal exceptions, debugging, warnings, and hex dumps of network packets. ALL may be specified to indicate all messages should be logged. The ALL argument will produce more messages than EXC,DEB,WAR,HEX combined. NON will not print anything to the console including exceptions. +
jcifs.smb.client.attrExpirationPeriod +Attributes of a file are cached for attrExpirationPeriod milliseconds. The default is 5000. This greatly improves performance because it eliminates redundant calls to the server however it is possible that two separate instances of SmbFiles pointing to the same resource may produce different results in awkward situations (e.g. s1.canRead() may return true even though s2.delete() was called immediately before). For maximum reliability, turn off attribute expiration by setting this property to 0. +
jcifs.smb.client.responseTimeout +The time period in milliseconds that the client will wait for a response to a request from the server. The default value is 30000. Under poor network conditions you may wish to increase this value but jcifs.smb.client.soTimeout should be increased as well to accommodate. +
jcifs.smb.client.soTimeout +To prevent the client from holding server resources unnecessarily, sockets are closed after this time period if there is no activity. This time is specified in milliseconds. The default is 35000. +
jcifs.netbios.cachePolicy +When a NetBIOS name is resolved with the NbtAddress class it is cached to reduce redundant name queries. This property controls how long, in seconds, these names are cached. The default is 30 seconds, 0 is no caching, and -1 is forever. +
jcifs.netbios.hostname +This property will force port 139 rather than the default port 445. Normally a CIFS client connecting to port 139 must present a NetBIOS name for itself to the server. JCIFS dynamically generates a name (e.g. JCIFS35_177_E6) for this purpose however it may be desirable to set this property to a specific name(e.g. PROD_FEED3) for reasons such as server accounting purposes. + +
jcifs.smb.client.listSize +One command that may be individually tuned is the TRANS2_FIND_FIRST/NEXT2 operation. It is provoked by the list() method of SmbFile (but not for smb://, smb://workgroup/, or smb://server/ URLs). The size of the data buffer used, in bytes, can be set with this property. The default size is 65535 bytes. On higher latency networks a value below the MTU (e.g. 1200) may result in better performance. + +
jcifs.smb.client.listCount +Similar to listSize property above, listCount is for tuning the TRANS2_FIND_FIRST/NEXT2 operation. It controls the maximum number of directory and file entries that should be returned with each request. The default is 200. On higher latency networks a lowever value (e.g. 15) may result in better performance. + +
jcifs.smb.client.lport +If a particular local port must be used for socket communications, perhaps because a firewall requires the source port to be a specific value, it can be set with this property(e.g. lport=5139). This has no effect on the remote port which is invariably 139. +
jcifs.netbios.soTimeout +To prevent the client from holding resources unnecessarily, the datagram socket used for nameservice queries is closed after this time period which is specified in milliseconds. The default is 5000. + +
jcifs.netbios.lport +If a particular local port must be used for socket communications, perhaps because a firewall requires the source port to be a specific value, it can be set with this property(e.g. lport=5137). This has no effect on the remote port which is invariably 137. +
jcifs.netbios.retryCount +The number of times a name query should be attempted if no answer is received. In adverse network conditions one may wish to increase this value however failed name queries take retryCount * retryDuration milliseconds. The default value is 2. Should probably increase jcifs.netbios.retryTimeout instead. +
jcifs.netbios.retryTimeout +The duration in milliseconds that the client will wait for a response to a name query. The default is 3000. +
jcifs.http.domainController +The DNS hostname or IP address of a server that should be used to authenticate HTTP clients with the NtlmSsp class (use by NtlmHttpFilter and NetworkExplorer). If this is not specified the jcifs.smb.client.domain 0x1C NetBIOS group name will be queried. It is not necessary for this to specify a real domain controller. The IP address of a workstation will do for development purposes. We do not support DCE/RPC NETLOGON. +See jCIFS NTLM HTTP Authentication Support for more information. +
jcifs.http.basicRelm +The realm for basic authentication. This property defaults to 'jCIFS'. +
jcifs.http.enableBasic +Setting this property to true enables basic authentication over HTTPS only. +
jcifs.http.insecureBasic +Setting this property to true enables basic authentication over plain HTTP. This configuration passes user credentials in plain text over the network. It should not be used in environment where security is required. +
jcifs.smb.lmCompatibility +This client can perform NTLMv2 with and without NTLMSSP as well as NTLMv1. The default lmCompatibility level is 3 to indicate that NTLMv2 should be favored (although prior to JCIFS 1.3.0, NTLMv1 was the default). This can be changed by using this property with an integer that specifies the "level" of security: +
    +
  • 0,1 -- Sends LM and NTLM responses. +
  • 2 -- Sends only the NTLM response. This is more secure than Levels 0 and 1, because it eliminates the cryptographically-weak LM response. +
  • 3,4,5 -- Sends LMv2 and NTLMv2 data. NTLMv2 session security is also negotiated if the server supports it. This is the default behavior (in 1.3.0 or later). +
+These values mirror those used with the Windows registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa used for the same purpose. See the page entitled The NTLM Authentication Protocol for a technical description of these authentication mechanisms. +

+This must be set to 0 for older versions of Samba (3.0.x) as it seems they do not support *raw* NTLMSSP and currently JCIFS does not support SPNEGO. +

jcifs.smb.client.ssnLimit +No more than this number of sessions will be open over the same transport. If the limit is reached, new redundant transports will be opened to accomodate more sessions. If this value is set to 1 a new transport will be created for each session. The default value is 250. Using a value that is too high may result in ERRSVR/90: Too many Uids active on this session. +
jcifs.smb.client.signingPreferred +The JCIFS client will negotiate SMB signing with a server that requires it. If the server does not require SMB signing but supports it, it will be necessary to set this property to true for signing to occur. Signing is required by default with Windows 2003. Currently it is not possible to use singing with NTLM HTTP authentication because the password hases are required to generate the signing key which is known only to the client (Internet Exploiter). It will be necessary to implement the NETLOGON RPC to fully support signing with NTLM HTTP authentication. We do not support DCE/RPC NETLOGON. +
jcifs.http.loadBalance +If a jcifs.smb.client.domain property is specified (and domainController is not specified) the NtlmHttpFilter will query for domain controllers by name. If this property is true the Filter will rotate through the list of domain controllers when authenticating users. The default value is true. The jcifs.netbios.lookupRespLimit property can also be used to limit the number of domain controllers used. +
jcifs.netbios.lookupRespLimit +The 0x1C NetBIOS name query returns a list of domain controllers. It is believed that the servers at the top of this list should be favored. This property limits the range of servers returned by name queries. The default value is 5 meaning the top 5 domain controllers will be used. +
jcifs.smb.client.logonShare +The shared name against which SmbSession.logon() will authenticate users. The default value is IPC$ but changing it can be used to create simple group based access control for the NtlmHttpFilter or other applications that use SmbSession.logon(). See the SmbSession API documentation for details. +
jcifs.smb.client.dfs.disabled +If this property is true, domain based DFS referrals will be disabled. The default value is false. This property can be important in non-domain environments where domain-based DFS referrals that normally run when JCIFS first tries to resolve a path would timeout causing a long startup delay (e.g. running JCIFS only on the local machine without a network like on a laptop). +
jcifs.smb.client.dfs.ttl +The time in seconds that DFS topology information should be cached. The default value is 300 seconds (although the trusted domains list is cached for 10 times jcifs.smb.client.dfs.ttl). +
jcifs.smb.client.dfs.strictView +This property controls how JCIFS behaves if it fails to enumerate DFS roots but succeeds to enumerate shares. By default this value is false to indicate that JCIFS should quitely return the list of shares even if the DFS root enumeration fails. If this value is set to true, an exception will be thrown if DFS information cannot be successfully retrieved (e.g. an SmbAuthException due to insufficient access). +
Advanced Properties
+These should not be changed
jcifs.smb.client.nativeOs +Specifies the NativeOS field in the SMB_COM_SESSION_SETUP_ANDX command. The default is the os.name system property. +
jcifs.smb.client.nativeLanMan +Specifies the NativeLanMan field in the SMB_COM_SESSION_SETUP_ANDX request. The default is "jCIFS". +
jcifs.smb.client.maxMpxCount +This client can send and receive messages concurrently over the same socket. The number of simultaneous outstanding transactions with a given server is controlled by this property. The default is 10. Under extremely unlikely circumstances this value may need to be adjusted to achive optimal throughput. It is more likely this property would be set to 1 to support a deficient server. +
jcifs.smb.client.useNTSmbs +This property is largely ignored. +
jcifs.smb.client.useUnicode +This client will use Unicode strings wherever negotiated. Setting this property to false will remove Unicode capability and therefore use only 8 bit strings will used (although Unicode will still be used to accomodate a few protocol bugs). +
jcifs.netbios.client.writeSize +The size of buffer in bytes that the NetBIOS Socket layer uses to write data to the raw socket. The default is 1500 and in effect limits the NetBIOS session service outbound message size. +
jcifs.smb.client.flags2 +A carefully crafted integer may be used with this property to specify the flags2 field of the SMB header. +
jcifs.smb.client.capabilities +A carefully crafted integer may be used with this property to specify the capabilities field of the SMB_COM_SESSION_SETUP_ANDX command. +
jcifs.smb.client.rcv_buf_size +One buffer is used to decode incoming packets. The size of this buffer may be specified, in bytes, using this property. The default is 60416. +
jcifs.smb.client.snd_buf_size +One buffer is used to encode outgoing packets. The size of this buffer may be specified, in bytes, using this property. The default is 16644. +
jcifs.smb.client.serviceType +The service type should always be '?????' which means that the server should resolve it and to my knowledge this resolution mechanism has never failed. But ... should one wish to experiment you can set it with this property. Service types can be at least A:, LPT1:, IPC, and COMM. +
jcifs.smb.client.<smb_ident>.<smb_ident> +It is possible to "tune" batching (a.k.a chaining) by specifying and integer batch level for a pair of SMB messages. See Batching for details. +
jcifs.smb.client.useBatching +To turn off batching altogether specify false for this property. The default is true. +
jcifs.smb.client.tcpNoDelay +If this property is true, setTcpNoDelay( true ) will be called on all SMB transport sockets. The default value is false (Nagle's algorithm is enabled). +
jcifs.smb.client.transaction_buf_size +The maximum SMB transaction buffer size. The default is 0xFFFF - 512. +
jcifs.smb.maxBuffers +The maximum number of of jcifs.smb.client.transaction_buf_size buffers that the buffer cache will create. The default is 16. +
+ + diff --git a/docs/pipes.html b/docs/pipes.html new file mode 100644 index 0000000..b445c63 --- /dev/null +++ b/docs/pipes.html @@ -0,0 +1,225 @@ + + + + + + + + + + +

Using JCIFS to Connect to Win32 Named Pipes

+ +The Named Pipe client functions of the Windows SDK have been implemented with jCIFS (Named Pipes are implemented over SMB) allowing Java programs to directly communicate with Win32 Named Pipe server processes. +

+ +Note: Named Pipes are slow and less portable compared to sockets. There are few reasons why one might write a new application to use Win32 Named Pipes opposed to explicit network programming with Sockets. + +

+There are several Win32 functions for sending and receiving data with Named Pipes all of which have been normalized into the Java XxxputStream interface however a different SmbNamedPipe constructor parameter is necessary depending on which style of messaging is to be used on the wire. These differences can be summarized by the type of Win32 functions that would be used had the client code been written for the Windows platform. The type of Named Pipe and it's attributes are specified when a server Named Pipe is created with a CreateNamedPipe Win32 call. +
    + +
  • +CallNamedPipe To use the CallNamedPipe style of messaging use the SmbFile.PIPE_TYPE_CALL flag.
  • + +
  • +TransactNamedPipe To use the TransactNamedPipe style of messaging use the SmbFile.PIPE_TYPE_TRANSACT flag.
  • + +
  • +CreateFile The traditional file I/O oriented Named Pipe messaging used by the CreateFile, WriteFile, and ReadFile Win32 functions is used when the SmbNamedPipe constructor is not passed either of the above mentioned flags.
  • + +
+ + +

See also: + + + +

CallNamedPipe and TransactNamedPipe Style Named Pipes

+ +There are several ways to obtain an InputStream and/or OutputStream with a Win32 Named Pipe server process. First, the open flags and mode of the server Named Pipe must be known. If for example, the following Win32 call was issued to create the server Named Pipe: + +
+h = CreateNamedPipe("\\\\.\\PIPE\\foo",
+        PIPE_ACCESS_DUPLEX,
+        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
+        10, bufferSize, bufferSize, NMPWAIT_WAIT_FOREVER, NULL);
+
+ +This would create a Transact oriented Named Pipe. To connect to this type of Named Pipe, the corresponding jCIFS code could be used: + +
+SmbNamedPipe pipe = new SmbNamedPipe( "smb://server/IPC$/PIPE/foo",
+        SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_CALL );
+OutputStream out = pipe.getNamedPipeOutputStream();
+InputStream in = pipe.getNamedPipeInputStream();
+
+ +If a message is written to the OutputStream, it's response can then be read from the InputStream. Take care that the same SmbNamedPipe instance is used with getNamedPipeOutputStream and getNamedPipeInputStream or the streams will not be connected to the same Named Pipe server instance. +

+An alternative sample of jCIFS code that would provoke the TransactNamedPipe style of I/O would look like: + +
+SmbNamedPipe pipe = new SmbNamedPipe( "smb://server/IPC$/foo",
+        SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_TRANSACT );
+OutputStream out = pipe.getNamedPipeOutputStream();
+InputStream in = pipe.getNamedPipeInputStream();
+
+ +Again, writing to the OutputStream obtained from this pipe will result in data being available in it's InputStream. Also, note the lack of "/PIPE" in this SMB URL. + +

File I/O Style Named Pipes

+ +The other type of Named Pipe can be created on the server by not specifying a pipe mode of PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE with the CreateNamedPipe Win32 function. With this file I/O oriented Named Pipe, the corresponding jCIFS code could be used: + +
+SmbNamedPipe pipe = new SmbNamedPipe( "smb://server/IPC$/foo",
+        SmbNamedPipe.PIPE_TYPE_RDWR );
+InputStream in = pipe.getNamedPipeInputStream();
+OutputStream out = pipe.getNamedPipeOutputStream();
+
+ +Notice that for file I/O oriented Named Pipes the PIPE_TYPE_TRANSACT parameter is not specified and there is no PIPE in the URL. Incedentally, SmbFileInputStream or SmbFileOutputStream may be used to read or write to this type of Named Pipe as one might do with a regular file. However you cannot read and write to the same Named Pipe server instance without using SmbNamedPipe to associate the streams. +

+Finally, if the server process is not ready to process the request a "All pipe instances are busy" error may result in which case it will be necessary to sleep momentarily and try again. + +

Running the CallNamedPipe.java Example Program

+ +The examples/CallNamedPipe.java program and examples/pipes/createnp.exe utility can be used to explore Named Pipes and the jCIFS Named Pipe client functionality. They, along with several other Named Pipe example programs and Win32 utility programs, were used to test the jCIFS implementation of Named Pipes. Users trying to write their own jCIFS Named Pipe clients might consult these programs to gain a better understanding of how jCIFS works with respect to Named Pipes. +

+To run the CallNamedPipe example, which issues a Transact style Named Pipe call, create a Transact oriented Named Pipe with the createnp.exe utility like: + +
+C:\TEMP> createnp
+dwOpenMode
+  0x00000003 PIPE_ACCESS_DUPLEX
+  0x00000001 PIPE_ACCESS_INBOUND
+  0x00000002 PIPE_ACCESS_OUTBOUND
+  0x80000000 FILE_FLAG_WRITE_THROUGH
+  0x40000000 FILE_FLAG_OVERLAPPED
+  0x00040000 WRITE_DAC
+  0x00080000 WRITE_OWNER
+  0x01000000 ACCESS_SYSTEM_SECURITY
+dwPipeMode
+  0x00000000 PIPE_TYPE_BYTE
+  0x00000004 PIPE_TYPE_MESSAGE
+  0x00000000 PIPE_READMODE_BYTE
+  0x00000002 PIPE_READMODE_MESSAGE
+  0x00000000 PIPE_WAIT
+  0x00000001 PIPE_NOWAIT
+defaults
+  inFile     = <read from pipe input>
+  outFile    = <write to pipe output>
+  dwOpenMode = PIPE_ACCESS_DUPLEX
+  dwPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT
+  bufferSize = 65535
+
+createnp \\.\pipe\name /I inFile /O outFile /M mode /P pmode /B bufferSize
+
+C:\TEMP> createnp \\.\pipe\foo /P 0x6
+
+ +The 0x6 for the dwPipeMode parameter was determined by ORing together the hexadecimal values for PIPE_TYPE_MESSAGE (0x4) and PIPE_READMODE_MESSAGE (0x2). The Windows Calculator program in Scientific mode can help you with generating these values. See the CreateNamedPipe Win32 SDK Documentation for the exact meaning of these parameters. +

+Now compile and run the CallNamedPipe.java program like: + +
+$ java -Djcifs.properties=my.prp CallNamedPipe smb://server/IPC$/PIPE/foo in out
+
+ +This will read a buffer full of the file in which will be echoed by the createnp server process and written to the out file. The createnp program will exit and report success: + +
+C:\TEMP> createnp \\.\pipe\foo /P 0x6
+Success: operation performed successfully
+
+ + +
+ + Last updated Mar 18, 2009
jcifs-1.3.7
+ Copyright © 2004 The JCIFS Project
+validate this page
+ + diff --git a/docs/pipes.xml b/docs/pipes.xml new file mode 100644 index 0000000..988c20a --- /dev/null +++ b/docs/pipes.xml @@ -0,0 +1,125 @@ + + + + +Using JCIFS to Connect to Win32 Named Pipes + +The Named Pipe client functions of the Windows SDK have been implemented with jCIFS (Named Pipes are implemented over SMB) allowing Java programs to directly communicate with Win32 Named Pipe server processes. +

+Note: Named Pipes are slow and less portable compared to sockets. There are few reasons why one might write a new application to use Win32 Named Pipes opposed to explicit network programming with Sockets. +

+There are several Win32 functions for sending and receiving data with Named Pipes all of which have been normalized into the Java XxxputStream interface however a different SmbNamedPipe constructor parameter is necessary depending on which style of messaging is to be used on the wire. These differences can be summarized by the type of Win32 functions that would be used had the client code been written for the Windows platform. The type of Named Pipe and it's attributes are specified when a server Named Pipe is created with a CreateNamedPipe Win32 call. +

    +
  • CallNamedPipe To use the CallNamedPipe style of messaging use the SmbFile.PIPE_TYPE_CALL flag.
  • +
  • TransactNamedPipe To use the TransactNamedPipe style of messaging use the SmbFile.PIPE_TYPE_TRANSACT flag.
  • +
  • CreateFile The traditional file I/O oriented Named Pipe messaging used by the CreateFile, WriteFile, and ReadFile Win32 functions is used when the SmbNamedPipe constructor is not passed either of the above mentioned flags.
  • +
+ +

See also: +

+ +

CallNamedPipe and TransactNamedPipe Style Named Pipes

+ +There are several ways to obtain an InputStream and/or OutputStream with a Win32 Named Pipe server process. First, the open flags and mode of the server Named Pipe must be known. If for example, the following Win32 call was issued to create the server Named Pipe: + +
+h = CreateNamedPipe("\\\\.\\PIPE\\foo",
+        PIPE_ACCESS_DUPLEX,
+        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
+        10, bufferSize, bufferSize, NMPWAIT_WAIT_FOREVER, NULL);
+
+ +This would create a Transact oriented Named Pipe. To connect to this type of Named Pipe, the corresponding jCIFS code could be used: + +
+SmbNamedPipe pipe = new SmbNamedPipe( "smb://server/IPC$/PIPE/foo",
+        SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_CALL );
+OutputStream out = pipe.getNamedPipeOutputStream();
+InputStream in = pipe.getNamedPipeInputStream();
+
+ +If a message is written to the OutputStream, it's response can then be read from the InputStream. Take care that the same SmbNamedPipe instance is used with getNamedPipeOutputStream and getNamedPipeInputStream or the streams will not be connected to the same Named Pipe server instance. +

+An alternative sample of jCIFS code that would provoke the TransactNamedPipe style of I/O would look like: + +

+SmbNamedPipe pipe = new SmbNamedPipe( "smb://server/IPC$/foo",
+        SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_TRANSACT );
+OutputStream out = pipe.getNamedPipeOutputStream();
+InputStream in = pipe.getNamedPipeInputStream();
+
+ +Again, writing to the OutputStream obtained from this pipe will result in data being available in it's InputStream. Also, note the lack of "/PIPE" in this SMB URL. + +

File I/O Style Named Pipes

+ +The other type of Named Pipe can be created on the server by not specifying a pipe mode of PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE with the CreateNamedPipe Win32 function. With this file I/O oriented Named Pipe, the corresponding jCIFS code could be used: + +
+SmbNamedPipe pipe = new SmbNamedPipe( "smb://server/IPC$/foo",
+        SmbNamedPipe.PIPE_TYPE_RDWR );
+InputStream in = pipe.getNamedPipeInputStream();
+OutputStream out = pipe.getNamedPipeOutputStream();
+
+ +Notice that for file I/O oriented Named Pipes the PIPE_TYPE_TRANSACT parameter is not specified and there is no PIPE in the URL. Incedentally, SmbFileInputStream or SmbFileOutputStream may be used to read or write to this type of Named Pipe as one might do with a regular file. However you cannot read and write to the same Named Pipe server instance without using SmbNamedPipe to associate the streams. +

+Finally, if the server process is not ready to process the request a "All pipe instances are busy" error may result in which case it will be necessary to sleep momentarily and try again. + +

Running the CallNamedPipe.java Example Program

+ +The examples/CallNamedPipe.java program and examples/pipes/createnp.exe utility can be used to explore Named Pipes and the jCIFS Named Pipe client functionality. They, along with several other Named Pipe example programs and Win32 utility programs, were used to test the jCIFS implementation of Named Pipes. Users trying to write their own jCIFS Named Pipe clients might consult these programs to gain a better understanding of how jCIFS works with respect to Named Pipes. +

+To run the CallNamedPipe example, which issues a Transact style Named Pipe call, create a Transact oriented Named Pipe with the createnp.exe utility like: + +

+C:\TEMP> createnp
+dwOpenMode
+  0x00000003 PIPE_ACCESS_DUPLEX
+  0x00000001 PIPE_ACCESS_INBOUND
+  0x00000002 PIPE_ACCESS_OUTBOUND
+  0x80000000 FILE_FLAG_WRITE_THROUGH
+  0x40000000 FILE_FLAG_OVERLAPPED
+  0x00040000 WRITE_DAC
+  0x00080000 WRITE_OWNER
+  0x01000000 ACCESS_SYSTEM_SECURITY
+dwPipeMode
+  0x00000000 PIPE_TYPE_BYTE
+  0x00000004 PIPE_TYPE_MESSAGE
+  0x00000000 PIPE_READMODE_BYTE
+  0x00000002 PIPE_READMODE_MESSAGE
+  0x00000000 PIPE_WAIT
+  0x00000001 PIPE_NOWAIT
+defaults
+  inFile     = <read from pipe input>
+  outFile    = <write to pipe output>
+  dwOpenMode = PIPE_ACCESS_DUPLEX
+  dwPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT
+  bufferSize = 65535
+
+createnp \\.\pipe\name /I inFile /O outFile /M mode /P pmode /B bufferSize
+
+C:\TEMP> createnp \\.\pipe\foo /P 0x6
+
+ +The 0x6 for the dwPipeMode parameter was determined by ORing together the hexadecimal values for PIPE_TYPE_MESSAGE (0x4) and PIPE_READMODE_MESSAGE (0x2). The Windows Calculator program in Scientific mode can help you with generating these values. See the CreateNamedPipe Win32 SDK Documentation for the exact meaning of these parameters. +

+Now compile and run the CallNamedPipe.java program like: + +

+$ java -Djcifs.properties=my.prp CallNamedPipe smb://server/IPC$/PIPE/foo in out
+
+ +This will read a buffer full of the file in which will be echoed by the createnp server process and written to the out file. The createnp program will exit and report success: + +
+C:\TEMP> createnp \\.\pipe\foo /P 0x6
+Success: operation performed successfully
+
+ +
diff --git a/docs/plain.xsl b/docs/plain.xsl new file mode 100644 index 0000000..e034612 --- /dev/null +++ b/docs/plain.xsl @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +

+

+
+ + + +
+ + Last updated
+
+ Copyright © 2004
+ validate this page +
+ + +
+ + +

+
+ +
+ diff --git a/docs/proj.xsl b/docs/proj.xsl new file mode 100644 index 0000000..33bba11 --- /dev/null +++ b/docs/proj.xsl @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:value-of select="title"/> + + +
+ +
+ JCIFS +

+
+

+ +

+ + + +
+ +
+ + +

Links

+ +
+
+ +

+ +
+
+ +
+
+
+
+ + +

News

+ + + + +

+ +
+
+ +

+ + + + + + + + + + + + diff --git a/docs/prp.txt b/docs/prp.txt new file mode 100644 index 0000000..0453550 --- /dev/null +++ b/docs/prp.txt @@ -0,0 +1,66 @@ +jcifs.encoding +jcifs.http.basicRealm +jcifs.http.domainController +jcifs.http.enableBasic +jcifs.http.insecureBasic +jcifs.http.loadBalance +jcifs.netbios.baddr +jcifs.netbios.cachePolicy +jcifs.netbios.hostname +jcifs.netbios.laddr +jcifs.netbios.lmhosts +jcifs.netbios.lookupRespLimit +jcifs.netbios.lport +jcifs.netbios.rcv_buf_size +jcifs.netbios.retryCount +jcifs.netbios.retryTimeout +jcifs.netbios.scope +jcifs.netbios.snd_buf_size +jcifs.netbios.soTimeout +jcifs.netbios.wins +jcifs.resolveOrder +jcifs.smb.client.attrExpirationPeriod +jcifs.smb.client.capabilities +jcifs.smb.client.codepage +jcifs.smb.client.disablePlainTextPasswords +jcifs.smb.client.domain +jcifs.smb.client.flags2 +jcifs.smb.client.laddr +jcifs.smb.client.listCount +jcifs.smb.client.listSize +jcifs.smb.client.logonShare +jcifs.smb.client.lport +jcifs.smb.client.maxMpxCount +jcifs.smb.client.nativeLanMan +jcifs.smb.client.OpenAndX.ReadAndX +jcifs.smb.client.password +jcifs.smb.client.rcv_buf_size +jcifs.smb.client.ReadAndX.Close +jcifs.smb.client.responseTimeout +jcifs.smb.client.serviceType +jcifs.smb.client.SessionSetupAndX.TreeConnectAndX +jcifs.smb.client.signingPreferred +jcifs.smb.client.snd_buf_size +jcifs.smb.client.soTimeout +jcifs.smb.client.ssnLimit +jcifs.smb.client.tcpNoDelay +jcifs.smb.client.transaction_buf_size +jcifs.smb.client.TreeConnectAndX.CheckDirectory +jcifs.smb.client.TreeConnectAndX.CreateDirectory +jcifs.smb.client.TreeConnectAndX.Delete +jcifs.smb.client.TreeConnectAndX.DeleteDirectory +jcifs.smb.client.TreeConnectAndX.OpenAndX +jcifs.smb.client.TreeConnectAndX.QueryInformation +jcifs.smb.client.TreeConnectAndX.Rename +jcifs.smb.client.TreeConnectAndX.Transaction +jcifs.smb.client.useBatching +jcifs.smb.client.useNTSmbs +jcifs.smb.client.useNtStatus +jcifs.smb.client.username +jcifs.smb.client.useUnicode +jcifs.smb.client.WriteAndX.Close +jcifs.smb.client.WriteAndX.ReadAndX +jcifs.smb.lmCompatibility +jcifs.smb.maxBuffers +jcifs.util.loglevel +os.name diff --git a/docs/quotes.txt b/docs/quotes.txt new file mode 100644 index 0000000..986d9a2 --- /dev/null +++ b/docs/quotes.txt @@ -0,0 +1,12 @@ +"for my opinion, jcifs is one of the best supported open source projects!" - paul + +"Hi there, I was very impressed to stumble across jcifs. I was so excited, I did a little dance. I have configured Tomcat with the jcifs.http.NtlmHttpFilter, and it is working beautifully." - Andrew S. + +"It is a fine library indeed." - Bren C. + +"Btw. jCIFS is great product - we use this in production (0.7.8) - in next 2 weeks we will test 0.7.14 with about 2000 concurrent users in our intranet." - Sylwester L. + +"thanks alot i find want i want and am writing my program which shows the shared directories and downloads by clicking them. thank you a alot! with my best wishes............" - spawnnn + +"Many thanks for an excellent product -- I've been using it for a while now and it rocks!" - Persona Non Grata + diff --git a/docs/resolver.html b/docs/resolver.html new file mode 100644 index 0000000..377b94b --- /dev/null +++ b/docs/resolver.html @@ -0,0 +1,236 @@ + + + + + + + + + +

Setting Name Resolution Properties

+ +Server names can be resolved using NetBIOS broadcast queries, WINS queries, lmhosts files, or DNS. The individual methods as well as the order in which they will be used can be set using the jcifs.resolveOrder property. Several other properties are important to how server names are resolved and are discussed below. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name Resolution Properties
jcifs.netbios.wins +The IP address of the WINS server(or more formally NBNS). This is only required when accessing hosts on different subnets although it is recomended if a WINS server is being used. +
jcifs.netbios.baddr +The local network's broadcast address. It may be necessary to set this for certain network configurations because the default of 255.255.255.255 may otherwise throw a "Network is unreachable" IOException. For example if the local host's IP address is 192.168.1.15, the broadcast address would likely be 192.168.1.255. +
jcifs.resolveOrder +A comma separated list of name resolution method identifiers that specify which methods will be used and in what order to resolve hostnames. The possible identifiers are LMHOSTS, WINS, BCAST, and DNS. +
jcifs.netbios.lmhosts +The path to an lmhosts file containing a map of IP addresses to hostnames. The format of this file is identical to that of the Windows lmhosts file format with a few exceptions noted below. +
jcifs.netbios.scope +This is rare but NetBIOS provides for a "scope id" to be used in a attempt to conceal groups of machines on the same network. Ask your network administrator if scope id is used. If so, it must be set using this property or name queries will fail. +
+ + +

The resolveOrder Property

+ +The resolveOrder property specifies a comma separated list of name resolution methods to use as well as the order in which they should be used. The method names are LMHOSTS, WINS, BCAST, and DNS. The default order is: + +
+resolveOrder=LMHOSTS,WINS,DNS,BCAST
+
+ +or if the jcifs.netbios.wins property is not defined the default will be just + +
+resolveOrder=LMHOSTS,DNS,BCAST
+
+ + +Note: The above defaults were changed in 1.3.3 from LMHOSTS,WINS,BCAST,DNS and LMHOSTS,BCAST,DNS respectively. Meaning BCAST was moved to after DNS. + +Both the UniAddress and NbtAddress classes honor the jcifs.resolveOrder property but the UniAddress class is used almost exclusively by jCIFS internally whereas the NbtAddress class will ignore the "DNS" token. +

+The DNS method uses java.net.InetAddress.getByName(). So the operating systems default name resolution mechanism is responsible for resolving DNS names(i.e. if you wish to specify a DNS server you must modify the DNS configuration of the system on which jCIFS will be running). To resolve a server name, each method is queried in order. If at any point the name is successfully resolved no further methods are queried. + +

+As an example: + +
+resolveOrder=DNS,BCAST
+
+ +This would result in DNS being queried first. If the DNS query fails, a NetBIOS name query will be broadcast on 255.255.255.255 or the address specified by the jcifs.netbios.baddr property. Should this broadcast query fail, an UnknownHostException will result. The lmhosts file and WINS methods will not be attempted regardless of whether or not the jcifs.netbios.lmhosts or jcifs.netbios.wins properties are set. + +

+ +It is noteworthy that failed BCAST queries take 6 seconds to timeout (by default retryTimeout is 3000 and retryCount is 2). Therefore it is advantageous to specify a resolveOrder of: + +
+resolveOrder=LMHOSTS,WINS,DNS
+
+ +without the BCAST method if it is expected that all hosts should be resolved by WINS or DNS. This is much faster if queries are anticipated to occasionally fail (e.g. an SMB crawler program will run much faster without BCAST). + +

The lmhosts Property

+ +The optional lmhosts property specifies the path to an lmhosts file. This file should contain IP address to server name mappings. When the LMHOSTS name resolution method is queried, these entries will be consulted. Generally lmhosts files are used to allow access to hosts on different networks if a WINS server is not provided. It is analogous to the /etc/hosts file on a UNIX system. + +

+ +The format of this file is identical to that of the Microsoft Windows lmhosts file. A simple lmhosts file might look like: + +
+# This is a comment
+192.168.1.15  nano
+192.168.1.16 angus
+
+ +Where each entry is just an IP address followed by the server name for that host. A more sophisticated example might look like: + +
+# This is a comment
+150.34.26.16 freto #PRE
+#INCLUDE \\FRETO\TEMP\nlmhosts
+
+192.168.1.15 nano
+
+ +The #PRE tag is ignored by jCIFS because they are not necessary. It indicates that a name should be pre-loaded into the server lookup table. However because jCIFS provides for specifying a resolveOrder where an lmhosts file might be queried after a different method it is not desirable to explicitly populate the lookup table. Entries are loaded as they are encountered in the file however so names are effectively always pre-loaded. + +

+ +The #INCLUDE tag is not ignored by jCIFS. Where encountered, jCIFS will retrieve the file associated with this UNC name and parse it's contents as if the file were included at that location. + +

+ + +#DOM tags are ignored but the #BEGIN_ALTERNATE / #END_ALTERNATE blocks are fully supported. The only incompatability with the Windows lmhosts file format is that quoted strings and \0xnn non-printable escape characters are not supported. + +

+ +The format for this file was chosen to be compatible with the Windows lmhosts file because it is conceivable that an existing system or network lmhosts file might be used. To use a systems existing lmhosts file one might set the jcifs.netbios.lmhosts property to point to the system lmhosts file for Windows NT with: + +
+lmhosts=C:\WINNT\system32\drivers\etc\lmhosts
+
+ +or on other Windows systems with perhaps: + +
+lmhosts=C:\WINDOWS\lmhosts
+
+ +To read a network lmhosts file, set the jcifs.netbios.lmhosts property like: + +
+lmhosts=conf/mylmhosts
+
+ +and create that file with contents such as: + +
+# Address of server hosting network lmhosts file
+192.168.1.16  freto
+#INCLUDE \\freto\netcfg\nlmhosts
+
+ +Ask your network administrator if lmhosts files are used and if you should use one in the context of your application. + +

Note: It so happens that DNS names may be specified in a jCIFS lmhosts file. But DNS names are not valid if the lmhosts file is to be read by Windows systems. + +
+ + Last updated Mar 18, 2009
jcifs-1.3.7
+ Copyright © 2004 The JCIFS Project
+validate this page
+ + diff --git a/docs/resolver.xml b/docs/resolver.xml new file mode 100644 index 0000000..e9385a9 --- /dev/null +++ b/docs/resolver.xml @@ -0,0 +1,138 @@ + + + +Setting Name Resolution Properties + +Server names can be resolved using NetBIOS broadcast queries, WINS queries, lmhosts files, or DNS. The individual methods as well as the order in which they will be used can be set using the jcifs.resolveOrder property. Several other properties are important to how server names are resolved and are discussed below. + +

+ + + + + + + + + + + + +
Name Resolution Properties
jcifs.netbios.wins +The IP address of the WINS server(or more formally NBNS). This is only required when accessing hosts on different subnets although it is recomended if a WINS server is being used. +
jcifs.netbios.baddr +The local network's broadcast address. It may be necessary to set this for certain network configurations because the default of 255.255.255.255 may otherwise throw a "Network is unreachable" IOException. For example if the local host's IP address is 192.168.1.15, the broadcast address would likely be 192.168.1.255. +
jcifs.resolveOrder +A comma separated list of name resolution method identifiers that specify which methods will be used and in what order to resolve hostnames. The possible identifiers are LMHOSTS, WINS, BCAST, and DNS. +
jcifs.netbios.lmhosts +The path to an lmhosts file containing a map of IP addresses to hostnames. The format of this file is identical to that of the Windows lmhosts file format with a few exceptions noted below. +
jcifs.netbios.scope +This is rare but NetBIOS provides for a "scope id" to be used in a attempt to conceal groups of machines on the same network. Ask your network administrator if scope id is used. If so, it must be set using this property or name queries will fail. +
+ +

The resolveOrder Property

+ +The resolveOrder property specifies a comma separated list of name resolution methods to use as well as the order in which they should be used. The method names are LMHOSTS, WINS, BCAST, and DNS. The default order is: + +
+resolveOrder=LMHOSTS,WINS,DNS,BCAST
+
+ +or if the jcifs.netbios.wins property is not defined the default will be just + +
+resolveOrder=LMHOSTS,DNS,BCAST
+
+ +Note: The above defaults were changed in 1.3.3 from LMHOSTS,WINS,BCAST,DNS and LMHOSTS,BCAST,DNS respectively. Meaning BCAST was moved to after DNS. + +Both the UniAddress and NbtAddress classes honor the jcifs.resolveOrder property but the UniAddress class is used almost exclusively by jCIFS internally whereas the NbtAddress class will ignore the "DNS" token. +

+The DNS method uses java.net.InetAddress.getByName(). So the operating systems default name resolution mechanism is responsible for resolving DNS names(i.e. if you wish to specify a DNS server you must modify the DNS configuration of the system on which jCIFS will be running). To resolve a server name, each method is queried in order. If at any point the name is successfully resolved no further methods are queried. + +

+As an example: + +

+resolveOrder=DNS,BCAST
+
+ +This would result in DNS being queried first. If the DNS query fails, a NetBIOS name query will be broadcast on 255.255.255.255 or the address specified by the jcifs.netbios.baddr property. Should this broadcast query fail, an UnknownHostException will result. The lmhosts file and WINS methods will not be attempted regardless of whether or not the jcifs.netbios.lmhosts or jcifs.netbios.wins properties are set. + +

+ +It is noteworthy that failed BCAST queries take 6 seconds to timeout (by default retryTimeout is 3000 and retryCount is 2). Therefore it is advantageous to specify a resolveOrder of: + +

+resolveOrder=LMHOSTS,WINS,DNS
+
+ +without the BCAST method if it is expected that all hosts should be resolved by WINS or DNS. This is much faster if queries are anticipated to occasionally fail (e.g. an SMB crawler program will run much faster without BCAST). + +

The lmhosts Property

+ +The optional lmhosts property specifies the path to an lmhosts file. This file should contain IP address to server name mappings. When the LMHOSTS name resolution method is queried, these entries will be consulted. Generally lmhosts files are used to allow access to hosts on different networks if a WINS server is not provided. It is analogous to the /etc/hosts file on a UNIX system. + +

+ +The format of this file is identical to that of the Microsoft Windows lmhosts file. A simple lmhosts file might look like: + +

+# This is a comment
+192.168.1.15  nano
+192.168.1.16 angus
+
+ +Where each entry is just an IP address followed by the server name for that host. A more sophisticated example might look like: + +
+# This is a comment
+150.34.26.16 freto #PRE
+#INCLUDE \\FRETO\TEMP\nlmhosts
+
+192.168.1.15 nano
+
+ +The #PRE tag is ignored by jCIFS because they are not necessary. It indicates that a name should be pre-loaded into the server lookup table. However because jCIFS provides for specifying a resolveOrder where an lmhosts file might be queried after a different method it is not desirable to explicitly populate the lookup table. Entries are loaded as they are encountered in the file however so names are effectively always pre-loaded. + +

+ +The #INCLUDE tag is not ignored by jCIFS. Where encountered, jCIFS will retrieve the file associated with this UNC name and parse it's contents as if the file were included at that location. + +

+ +#DOM tags are ignored but the #BEGIN_ALTERNATE / #END_ALTERNATE blocks are fully supported. The only incompatability with the Windows lmhosts file format is that quoted strings and \0xnn non-printable escape characters are not supported. + +

+ +The format for this file was chosen to be compatible with the Windows lmhosts file because it is conceivable that an existing system or network lmhosts file might be used. To use a systems existing lmhosts file one might set the jcifs.netbios.lmhosts property to point to the system lmhosts file for Windows NT with: + +

+lmhosts=C:\WINNT\system32\drivers\etc\lmhosts
+
+ +or on other Windows systems with perhaps: + +
+lmhosts=C:\WINDOWS\lmhosts
+
+ +To read a network lmhosts file, set the jcifs.netbios.lmhosts property like: + +
+lmhosts=conf/mylmhosts
+
+ +and create that file with contents such as: + +
+# Address of server hosting network lmhosts file
+192.168.1.16  freto
+#INCLUDE \\freto\netcfg\nlmhosts
+
+ +Ask your network administrator if lmhosts files are used and if you should use one in the context of your application. + +

Note: It so happens that DNS names may be specified in a jCIFS lmhosts file. But DNS names are not valid if the lmhosts file is to be read by Windows systems. + + diff --git a/docs/todo.txt b/docs/todo.txt new file mode 100644 index 0000000..8332a6a --- /dev/null +++ b/docs/todo.txt @@ -0,0 +1,41 @@ +TODO + +Possible UNC path issue related to DFS as described by Thomas Bley 29 Apr 2006 13:57:28 +0200. + +Integrate Kerberos patch (requires SPENGO rewrite) + +Implement full NTLMv2 support. + +Change the NTLM HTTP code, NtlmPasswordAuthentication and SmbTransport so that closing a transport invalidates any challenges. When this happends, trying to use the NPA will throw an SmbAuthException. An NPA with an invalid challenge should NEVER be used to access SMB resources (as it does now). This is also key to getting DFS to work with NetworkExplorer and Davenport. + +Replace UCS2-LE encoding/decoding with custom fast methods. Implement the changes in a way such that the language functions are not necessary. Test the client with j2me (although after 5 minutes on java.sun.com I was not able to find it). + +Switch to using "Buffer.java" style (provided there is no copying) like much of Eric's code. Already started to do this in 2.x (which was never released). + +Add more SMB URL support such as QUERY_STRING parameters. + +Interesting note: If you run examples/TransactNamedPipe.java against the IPC$/srvsvc it successfully echos the data (README.txt). Odd. + +Create ResourceBundle with internationalized error messages. + +Update NTLM HTTP Filter document. + +DONE(but not supported by NT) Specify last modified time in SMB_COM_CLOSE + +Implement these other methods? + + getParentFile() + isAbsolute() + getAbsolutePath() + getAbsoluteFile() + getCanonicalFile() + deleteOnExit() + listRoots() - doesn't apply really + createTempFile() + +Correct for Unicode alignment in Trans2FindFirst2Response from NT with +useUnicode=no bug? This incongruentcey between MS servers and their +support for Unicode is the source of problems (e.g. the way short names +are returned in SMB_COM_TRANS2_FIND_FIRST2 responses from NT with Unicode +on/off. Is this still true? + diff --git a/docs/wins.html b/docs/wins.html new file mode 100644 index 0000000..e796ffb --- /dev/null +++ b/docs/wins.html @@ -0,0 +1,83 @@ + + + + + + + + + +

WINS vs NBNS

+ +The Windows Internet Naming Service(WINS) is Microsoft's implementation of the NetBIOS Name Server(NBNS). This product and it's name is so pervasive in the industry that the term NBNS is not widely known. It is for this reason that the term 'WINS' has been chosen in favor if the more formal 'NBNS' for use in documentation, property names, etc. + +
+ + Last updated Mar 18, 2009
jcifs-1.3.7
+ Copyright © 2004 The JCIFS Project
+validate this page
+ + diff --git a/docs/wins.xml b/docs/wins.xml new file mode 100644 index 0000000..19a6a25 --- /dev/null +++ b/docs/wins.xml @@ -0,0 +1,8 @@ + + + +WINS vs NBNS + +The Windows Internet Naming Service(WINS) is Microsoft's implementation of the NetBIOS Name Server(NBNS). This product and it's name is so pervasive in the industry that the term NBNS is not widely known. It is for this reason that the term 'WINS' has been chosen in favor if the more formal 'NBNS' for use in documentation, property names, etc. + + diff --git a/examples/10883563.doc b/examples/10883563.doc new file mode 100644 index 0000000..62644d9 --- /dev/null +++ b/examples/10883563.doc @@ -0,0 +1,6 @@ +C:\tmp>ktpass /princ HTTP/www.foo.net@WIN.NET /ptype KRB5_NT_PRINCIPAL /desonly /pass asj7j112233hh4455 /mapuser test2 +Targeting domain controller: ts0.win.net +Using legacy password setting method +Successfully mapped HTTP/www.foo.net to test2. +Key created. +Account test2 has been set for DES-only encryption. \ No newline at end of file diff --git a/examples/AclCrawler.java b/examples/AclCrawler.java new file mode 100644 index 0000000..5ec7c49 --- /dev/null +++ b/examples/AclCrawler.java @@ -0,0 +1,61 @@ +import java.util.LinkedList; +import java.util.ListIterator; +import java.net.MalformedURLException; +import java.io.IOException; +import jcifs.smb.*; + +public class AclCrawler { + + int maxDepth; + + AclCrawler( int maxDepth ) { + this.maxDepth = maxDepth; + } + + void traverse( SmbFile f, int depth ) throws MalformedURLException, IOException { + + if( depth == 0 ) { + return; + } + + SmbFile[] l = f.listFiles(); + + for(int i = 0; l != null && i < l.length; i++ ) { + try { + System.out.println( l[i] ); + ACE[] acl = l[i].getSecurity(); + for (int j = 0; j < acl.length; j++) { + System.out.print( acl[j] ); + int a = acl[j].getAccessMask(); + if ((a & 0xFF000000) != 0) { + if ((a & ACE.GENERIC_ALL) != 0) { + System.out.print( " GENERIC_ALL" ); + } + if ((a & ACE.GENERIC_WRITE) != 0) { + System.out.print( " GENERIC_WRITE" ); + } + if ((a & ACE.GENERIC_READ) != 0) { + System.out.print( " GENERIC_READ" ); + } + } + System.out.println(); + } + if( l[i].isDirectory() ) { + traverse( l[i], depth - 1 ); + } + } catch( IOException ioe ) { + ioe.printStackTrace(); + } + } + } + + public static void main(String[] argv) throws Exception { + if (argv.length < 2) { + System.err.println( "usage: AclCrawler " ); + System.exit(1); + } + int depth = Integer.parseInt( argv[1] ); + AclCrawler sc = new AclCrawler( depth ); + sc.traverse( new SmbFile( argv[0] ), depth ); + } +} diff --git a/examples/AllocInfo.java b/examples/AllocInfo.java new file mode 100644 index 0000000..8d9e1e5 --- /dev/null +++ b/examples/AllocInfo.java @@ -0,0 +1,11 @@ +import jcifs.smb.SmbFile; + +public class AllocInfo { + + public static void main( String argv[] ) throws Exception { + + SmbFile f = new SmbFile( argv[0] ); + System.out.println( f.getDiskFreeSpace() ); + } +} + diff --git a/examples/Append.java b/examples/Append.java new file mode 100644 index 0000000..390e974 --- /dev/null +++ b/examples/Append.java @@ -0,0 +1,23 @@ +import jcifs.smb.SmbFile; +import jcifs.smb.SmbFileOutputStream; + +public class Append { + + public static void main( String argv[] ) throws Exception { + + SmbFile f = new SmbFile( argv[0] ); + SmbFileOutputStream out = new SmbFileOutputStream( f, true ); + + byte[] msg; + int i = 0; + while( i++ < 3 ) { + msg = new String( "this is msg #" + i ).getBytes(); + out.write( msg ); + System.out.write( msg ); + Thread.sleep( 10000 ); +//out = new SmbFileOutputStream( f, true ); + } + + out.close(); + } +} diff --git a/examples/AuthListFiles.java b/examples/AuthListFiles.java new file mode 100644 index 0000000..52112b0 --- /dev/null +++ b/examples/AuthListFiles.java @@ -0,0 +1,53 @@ +import jcifs.netbios.NbtAddress; +import jcifs.util.*; +import jcifs.smb.*; +import java.util.Date; + +public class AuthListFiles extends NtlmAuthenticator { + + public static String readLine() throws Exception { + int c; + StringBuffer sb = new StringBuffer(); + while(( c = System.in.read() ) != '\n' ) { + if( c == -1 ) return ""; + sb.append( (char)c ); + } + return sb.toString().trim(); + } + + public AuthListFiles( String[] argv ) throws Exception { + NtlmAuthenticator.setDefault( this ); + + SmbFile file = new SmbFile( argv[0] ); + + SmbFile[] files = file.listFiles(); + + for( int i = 0; i < files.length; i++ ) { + System.out.print( " " + files[i].getName() ); + } + System.out.println(); + } + + protected NtlmPasswordAuthentication getNtlmPasswordAuthentication() { + System.out.println( getRequestingException().getMessage() + " for " + getRequestingURL() ); + try { + System.out.print( "username: " ); + String username = readLine(); + + System.out.print( "password: " ); + String password = readLine(); + + if( password.length() == 0 ) { + return null; + } + return new NtlmPasswordAuthentication( null, username, password ); + } catch( Exception e ) { + } + return null; + } + + + public static void main( String[] argv ) throws Exception { + new AuthListFiles( argv ); + } +} diff --git a/examples/CallNamedPipe.java b/examples/CallNamedPipe.java new file mode 100644 index 0000000..16efd37 --- /dev/null +++ b/examples/CallNamedPipe.java @@ -0,0 +1,35 @@ +import jcifs.smb.SmbNamedPipe; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; + +public class CallNamedPipe { + + public static void main( String[] argv ) throws Exception { + + if( argv.length < 2 ) { + throw new IllegalArgumentException( "args: " ); + } + + byte[] b = new byte[65535]; + FileInputStream fin = new FileInputStream( argv[1] ); + FileOutputStream fos = new FileOutputStream( argv[2] ); + + SmbNamedPipe pipe = new SmbNamedPipe( argv[0], + SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_CALL ); + OutputStream out = pipe.getNamedPipeOutputStream(); + InputStream in = pipe.getNamedPipeInputStream(); + + int n = fin.read( b ); + System.out.println( "writing " + n + " bytes" ); + out.write( b, 0, n ); + n = in.read(b); + System.out.println( "read " + n + " bytes" ); + fos.write(b, 0, n ); + + fin.close(); + fos.close(); + out.close(); + } +} diff --git a/examples/CheckAllDC.java b/examples/CheckAllDC.java new file mode 100644 index 0000000..361dd88 --- /dev/null +++ b/examples/CheckAllDC.java @@ -0,0 +1,23 @@ +import jcifs.netbios.NbtAddress; +import jcifs.*; +import jcifs.smb.*; + +public class CheckAllDC { + + public static void main( String argv[] ) throws Exception { + + if( argv.length < 2 ) { + System.err.println( "usage: CheckAllDC " ); + System.exit(1); + } + + NbtAddress[] addrs = NbtAddress.getAllByName( argv[0], 0x1C, null, null ); + + for( int i = 0; i < addrs.length; i++ ) { + System.out.println( addrs[i] ); + UniAddress dc = new UniAddress( addrs[i] ); + NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication( argv[1] ); + SmbSession.logon( dc, auth ); + } + } +} diff --git a/examples/CopyTo.java b/examples/CopyTo.java new file mode 100644 index 0000000..7de001d --- /dev/null +++ b/examples/CopyTo.java @@ -0,0 +1,12 @@ +import jcifs.smb.SmbFile; + +public class CopyTo { + + public static void main( String argv[] ) throws Exception { + + SmbFile from = new SmbFile( argv[0] ); + SmbFile to = new SmbFile( argv[1] ); + from.copyTo( to ); + } +} + diff --git a/examples/CopyToTest.java b/examples/CopyToTest.java new file mode 100644 index 0000000..abae930 --- /dev/null +++ b/examples/CopyToTest.java @@ -0,0 +1,29 @@ +import jcifs.smb.*; + +public class CopyToTest extends Thread { + + String url1, url2; + + CopyToTest(String url1, String url2) { + this.url1 = url1; + this.url2 = url2; + } + + public void run() { + for (int i = 0; i < 1; i++) { + try { + SmbFile file = new SmbFile(url1); + SmbFile to = new SmbFile(url2); + file.copyTo(to); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) throws Exception { + CopyToTest cts = new CopyToTest(args[0], args[1]); + cts.start(); + Thread.sleep(50000); + } +} diff --git a/examples/CountPerms.java b/examples/CountPerms.java new file mode 100644 index 0000000..36ac8d8 --- /dev/null +++ b/examples/CountPerms.java @@ -0,0 +1,114 @@ +import jcifs.smb.SmbFile; +import java.util.LinkedList; +import java.util.ListIterator; +import java.net.MalformedURLException; +import java.io.IOException; +import jcifs.util.Hexdump; + +public class CountPerms { + + int maxDepth; + int numFiles; + int numDirectories; + int numMeta; + int numMetaWithArch; + + int[] permissionCounts = new int[16]; + + String[] permissionNames = { + "Read Only", + "Hidden", + "System", + "Volume ID", + "Directory", + "Archive", + "Device", + "Normal", + "Temporary", + "Sparse", + "Reparse Point", + "Compressed", + "Offline", + "Content Indexed", + "Encrypted", + "Unknown" + }; + + CountPerms( int maxDepth ) { + this.maxDepth = maxDepth; + } + + void traverse( SmbFile f, int depth ) throws MalformedURLException, IOException { + + if( depth == 0 ) { + return; + } + + SmbFile[] l = f.listFiles(); + + for(int i = 0; l != null && i < l.length; i++ ) { + try { + int attrs = l[i].getAttributes(); + + if(( attrs & 0x7FEE ) != 0) { + if(( attrs & 0x7FCE ) != 0) { + numMeta++; + } + numMetaWithArch++; + } + for (int b = 0; b < 16; b++) { + if(( attrs & (1 << b)) != 0 ) { + permissionCounts[b]++; + } + } + + System.out.print( Hexdump.toHexString( l[i].getAttributes(), 4 ) + ": " ); + for( int j = maxDepth - depth; j > 0; j-- ) { + System.out.print( " " ); + } + System.out.println( l[i].getName() ); + if( l[i].isDirectory() ) { + traverse( l[i], depth - 1 ); + } + + if(( attrs & SmbFile.ATTR_DIRECTORY ) != 0 ) { + numDirectories++; + } else { + numFiles++; + } + } catch( IOException ioe ) { + System.out.println( l[i] + ": " + ioe.getMessage() ); + } + } + } + + void run( String url ) throws Exception { + traverse( new SmbFile( url ), maxDepth ); + + for (int p = 0; p < 16; p++) { + int len = 15 - permissionNames[p].length(); + while( len > 0 ) { + System.out.print( " " ); + len--; + } + System.out.println( permissionNames[p] + ": " + permissionCounts[p] ); + } + System.out.println( " num files: " + numFiles ); + System.out.println( " num directories: " + numDirectories ); + System.out.println( " num both: " + (numFiles + numDirectories) ); + System.out.println( " meta req: " + numMeta ); + System.out.println( "meta (incl. arch) req: " + numMetaWithArch ); + } + + public static void main(String[] argv) throws Exception { + + if( argv.length < 2 ) { + System.err.println( "usage: CountPerms " ); + System.exit(1); + } + + int depth = Integer.parseInt( argv[1] ); + CountPerms cp = new CountPerms( depth ); + cp.run( argv[0] ); + } +} diff --git a/examples/CrawlTest.java b/examples/CrawlTest.java new file mode 100644 index 0000000..6999f49 --- /dev/null +++ b/examples/CrawlTest.java @@ -0,0 +1,64 @@ +import jcifs.smb.SmbFile; +import java.util.LinkedList; +import java.util.ListIterator; +import java.net.MalformedURLException; +import java.io.IOException; + +public class CrawlTest extends Thread { + + SmbFile f; + int maxDepth; + + CrawlTest( SmbFile f, int maxDepth ) { + this.f = f; + this.maxDepth = maxDepth; + } + + void traverse( SmbFile f, int depth ) throws MalformedURLException, IOException { + + if( depth == 0 ) { + return; + } + + SmbFile[] l = f.listFiles(); + + for(int i = 0; l != null && i < l.length; i++ ) { + try { + for( int j = maxDepth - depth; j > 0; j-- ) { + System.out.print( " " ); + } + System.out.println( l[i] + " " + l[i].exists() ); + if( l[i].isDirectory() ) { + traverse( l[i], depth - 1 ); + } + } catch( IOException ioe ) { + System.out.println( l[i] + ":" ); + ioe.printStackTrace( System.out ); + } + } + } + + public void run() { + try { + traverse( f, maxDepth ); + } catch( Exception ex ) { + ex.printStackTrace(); + } + } + + public static void main(String[] argv) throws Exception { + if (argv.length < 3) { + System.err.println( "CrawlTest " ); + return; + } + + SmbFile f = new SmbFile( argv[0] ); + int numThreads = Integer.parseInt( argv[1] ); + int maxDepth = Integer.parseInt( argv[2] ); + + while (numThreads-- > 0 && System.in.read() == '\n') { + CrawlTest sc = new CrawlTest( f, maxDepth ); + sc.start(); + } + } +} diff --git a/examples/CreateFile.java b/examples/CreateFile.java new file mode 100644 index 0000000..d688d7b --- /dev/null +++ b/examples/CreateFile.java @@ -0,0 +1,11 @@ +import jcifs.smb.SmbFileOutputStream; + +public class CreateFile { + + public static void main( String argv[] ) throws Exception { + + SmbFileOutputStream out = new SmbFileOutputStream( argv[0], false ); + out.close(); + } +} + diff --git a/examples/Delete.java b/examples/Delete.java new file mode 100644 index 0000000..573b3ff --- /dev/null +++ b/examples/Delete.java @@ -0,0 +1,10 @@ +import jcifs.smb.*; + +public class Delete { + + public static void main( String argv[] ) throws Exception { + SmbFile f = new SmbFile( argv[0] ); + f.delete(); + } +} + diff --git a/examples/DnsSrv.java b/examples/DnsSrv.java new file mode 100644 index 0000000..a36eaa5 --- /dev/null +++ b/examples/DnsSrv.java @@ -0,0 +1,36 @@ +import java.util.*; +import javax.naming.*; +import javax.naming.directory.*; + +public class DnsSrv { + + String getDomain(String name) throws NamingException { + DirContext context; + NameNotFoundException ret = null; + + context = new InitialDirContext(); + for ( ;; ) { + try { + Attributes attributes = context.getAttributes( + "dns:/_ldap._tcp.dc._msdcs." + name, + new String[] { "SRV" } + ); + return name; + } catch (NameNotFoundException nnfe) { + ret = nnfe; + } + int dot = name.indexOf('.'); + if (dot == -1) + break; + name = name.substring(dot + 1); + } + + throw ret != null ? ret : new NamingException("invalid name"); + } + + public static void main(String argv[]) throws Exception { + DnsSrv dnsSrv = new DnsSrv(); + System.out.println(dnsSrv.getDomain(argv[0])); + } +} + diff --git a/examples/Equals.java b/examples/Equals.java new file mode 100644 index 0000000..26d3c34 --- /dev/null +++ b/examples/Equals.java @@ -0,0 +1,14 @@ +import jcifs.smb.SmbFile; + +public class Equals { + + public static void main( String argv[] ) throws Exception { + + SmbFile f1 = new SmbFile( argv[0] ); + SmbFile f2 = new SmbFile( argv[1] ); +System.out.println( f1 ); +System.out.println( f2 ); + System.err.println( f1.equals( f2 )); + } +} + diff --git a/examples/Exists.java b/examples/Exists.java new file mode 100644 index 0000000..9ab6c91 --- /dev/null +++ b/examples/Exists.java @@ -0,0 +1,15 @@ +import jcifs.smb.SmbFile; + +public class Exists { + + public static void main( String argv[] ) throws Exception { + + SmbFile f = new SmbFile( argv[0] ); + if( f.exists() ) { + System.out.println( argv[0] + " exists" ); + } else { + System.out.println( argv[0] + " does not exist" ); + } + } +} + diff --git a/examples/FileInfo.java b/examples/FileInfo.java new file mode 100644 index 0000000..889d93c --- /dev/null +++ b/examples/FileInfo.java @@ -0,0 +1,134 @@ +import java.util.*; +import java.text.*; +import java.net.*; +import jcifs.smb.*; + +public class FileInfo { + + static final String TYPES[] = { + "TYPE_COMM", + "TYPE_FILESYSTEM", + "TYPE_NAMED_PIPE", + "TYPE_PRINTER", + "TYPE_SERVER", + "TYPE_SHARE", + "TYPE_WORKGROUP" + }; + + public static void main( String argv[] ) throws Exception { + int i, start, end;; + SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yy hh:mm:ss a" ); + GregorianCalendar cal = new GregorianCalendar(); + SmbFile f; + + if( argv.length < 2 ) { + throw new IllegalArgumentException( "usage: FileInfo " ); + } + + if( argv.length == 3 ) { + SmbFile tmp = new SmbFile( argv[0] ); + f = new SmbFile( tmp.toString(), argv[1] ); + start = Integer.parseInt( argv[2] ); + } else { + f = new SmbFile( argv[0] ); + start = Integer.parseInt( argv[1] ); + } + + sdf.setCalendar( cal ); + + i = end = start; + do { + switch( i ) { + case 0: + System.out.println( " toString: " + f.toString() ); + break; + case 1: + System.out.println( " toURL: " + f.toURL() ); + break; + case 2: + System.out.println( " getName: " + f.getName() ); + break; + case 3: + System.out.println( " length: " + f.length() ); + break; + case 4: + System.out.println( " getLastModified: " + sdf.format( new Date( f.getLastModified() ))); + break; + case 5: + System.out.println( " isHidden: " + f.isHidden() ); + break; + case 6: + System.out.println( " isFile: " + f.isFile() ); + break; + case 7: + System.out.println( " isDirectory: " + f.isDirectory() ); + break; + case 8: + System.out.println( " hashCode: " + f.hashCode() ); + break; + case 9: + System.out.println( " getUncPath: " + f.getUncPath() ); + break; + case 10: + System.out.println( " getType: " + TYPES[f.getType()] ); + break; + case 11: + System.out.println( " getShare: " + f.getShare() ); + break; + case 12: + System.out.println( " getServer: " + f.getServer() ); + break; + case 13: + System.out.println( " getPath: " + f.getPath() ); + break; + case 14: + System.out.println( " getParent: " + f.getParent() ); + break; + case 15: + System.out.println( " lastModified: " + sdf.format( new Date( f.lastModified() ))); + break; + case 16: + System.out.println( "getDiskFreeSpace: " + f.getDiskFreeSpace() ); + break; + case 17: + System.out.println( " getDate: " + sdf.format( new Date( f.getDate() ))); + break; + case 18: + System.out.println( "getContentLength: " + f.getContentLength() ); + break; + case 19: + System.out.println( "getCanonicalPath: " + f.getCanonicalPath() ); + break; + case 20: + System.out.println( " exists: " + f.exists() ); + break; + case 21: + System.out.println( " canRead: " + f.canRead() ); + break; + case 22: + System.out.println( " canWrite: " + f.canWrite() ); + break; + case 23: + ACE[] security = f.getSecurity(true); + System.out.println( " Security:" ); + for (int ai = 0; ai < security.length; ai++) { + System.out.println(security[ai].toString()); + } + System.out.println(" Share Perm:"); + security = f.getShareSecurity(true); + for (int ai = 0; ai < security.length; ai++) { + System.out.println(security[ai].toString()); + } + break; + case 24: + System.out.println( " getDfsPath: " + f.getDfsPath() ); + break; + } + i++; + if( i == 25 ) { + i = 0; + } + } while( i != end ); + } +} + diff --git a/examples/FileOps.java b/examples/FileOps.java new file mode 100644 index 0000000..11c6e8d --- /dev/null +++ b/examples/FileOps.java @@ -0,0 +1,350 @@ +/* Test the following file operations: + * + * canRead + * false - a target that is already open by another process + * false - the target does not exist + * true - the file exists and there are no sharing issues + * canWrite + * true - the file exists and there are no sharing issues + * false - the file is marked read-only + * false - the file does not exist + * delete + * true - the file existed and was succcessfully deleted + * false - the target did not exist + * false - the target is a share, server, workgroup or similar + * false - the target or file under the target directory failed was read-only + * exists + * true - the target, share, IPC share, named pipe, server, or workgroup exists + * false - the opposite of the above + * isDirectory + * true - the target is a workgroup, server, share, or directory + * false - the target is not one of the above or does not exist + * isFile + * direct opposite of isDirectory + * isHidden + * true - target is share ending in $ or marked as hidden + * length + * the file was created to be no larger than ~2G and reports back the size specified + * mkdir + * true - a directory was created successfuly + * false - the directory could not be created + * renameTo + * true - the target was renamed + */ + +import jcifs.smb.*; +import java.io.IOException; +import java.util.Date; + +public class FileOps { + + static final int ATTR_ALL = SmbFile.ATTR_ARCHIVE | SmbFile.ATTR_HIDDEN | SmbFile.ATTR_READONLY | SmbFile.ATTR_SYSTEM; + + public static void main( String argv[] ) throws Exception { + + if( argv.length != 1 ) { + System.out.println( "Must provide an SMB URL of a remote location on which tests will be conducted." ); + System.exit( 1 ); + } + + SmbFile s = new SmbFile( argv[0] ); + SmbFile d = new SmbFile( s, "JcifsTestOpsDir/" ); + + // delete - Delete the directory if it exists + + try { + d.delete(); + } catch( SmbException se ) { + System.out.println( "okay - delete " + d + " failed: " + se.getMessage() ); + } + System.out.println( "okay - delete " + d + " successful" ); + + // exists - Test the directory that should not exist + + if( d.exists() ) { + System.out.println( "fail - " + d + " still exists" ); + System.exit( 1 ); + } else { + System.out.println( "okay - " + d + " does not exist" ); + } + + // mkdir - Create the directory + + d.mkdir(); + System.out.println( "okay - mkdir " + d + " successful" ); + + // exist - Test the directory which should exist now + + if( d.exists() ) { + System.out.println( "okay - " + d + " exists" ); + } else { + System.out.println( "fail - " + d + " was not successfuly created" ); + System.exit( 1 ); + } + + // mkdir - Try to create a directory even though it already exists + + try { + d.mkdir(); + System.out.println( "fail - mkdir " + d + " successful" ); + System.exit( 1 ); + } catch( SmbException se ) { + System.out.println( "okay - mkdir " + d + " failed: " + se.getMessage() ); + } + + // Create a file to test against + + SmbFile f = null; + try { + f = new SmbFile( d, "foo.txt" ); + SmbFileOutputStream o = new SmbFileOutputStream( f ); + o.write( "The Common Internet File System (CIFS) is the de-facto file sharing protocol on the Microsoft Windows platform. It is the underlying networking protocol used when accessing shares with Windows Explorer, the Network Neighborhood, via a Map Network Drive... dialog, the C:\\> net use * \\\\server\\share commands, or smbclient on UNIX, smbfs on Linux, and elsewhere.\r\n".getBytes() ); + o.close(); + } catch( IOException ioe ) { + System.out.println( "fail - could not create file " + d + "foo.txt: " + ioe.getMessage() ); + } + System.out.println( "okay - created file " + d + "foo.txt" ); + + // canRead - Test to see if the new file can be read + + if( f.canRead() ) { + System.out.println( "okay - canRead " + f + " successful" ); + } else { + System.out.println( "fail - canRead " + f + " failed" ); + System.exit( 1 ); + } + + // canWrite, getAttributes - Test the file for writing + + if( f.canWrite() && (f.getAttributes() & SmbFile.ATTR_READONLY) == 0 ) { + System.out.println( "okay - canWrite " + f + " successful" ); + } else { + System.out.println( "fail - canWrite " + f + " failed" ); + System.exit( 1 ); + } + + // setReadOnly + + try { + f.setReadOnly(); + System.out.println( "okay - setReadOnly " + f + " successful" ); + } catch( SmbException se ) { + System.out.println( "fail - setReadOnly " + f + " failed: " + se.getMessage() ); + } + + // canWrite - Test the file for writing + + if( f.canWrite() ) { + System.out.println( "fail - canWrite " + f + " returned true but it should have been marked read-only ... continuing on" ); + } else { + System.out.println( "okay - canWrite " + f + " failed" ); + } + + // Try to open the file for writing + + try { + SmbFileOutputStream w = new SmbFileOutputStream( f ); + w.close(); + System.out.println( "fail - successfuly opened " + f + " for writing even though it should be marked read-only ... continuing on" ); + } catch( IOException ioe ) { + System.out.println( "okay - correctly failed to open " + f + " for writing: " + ioe.getMessage() ); + } + + // renameTo - rename the file to bar.txt + + SmbFile b = new SmbFile( d, "bar.txt" ); + + try { + f.renameTo( b ); + System.out.println( "okay - renameTo " + f + " to " + b + " successful even with read-only" ); + try { + b.renameTo(f); + } catch( SmbException se ) { + System.out.println( "fail - but failed to rename file back to original!" ); + throw se; + } + } catch( SmbException se ) { + System.out.println( "fail - renameTo " + f + " should have been successful even though the file is marked read-only: " + se.getMessage() ); + } + + // setAttributes + + try { + f.setAttributes( 0xFFFF ); + System.out.println( "okay - setAttributes " + f + " successful" ); + } catch( SmbException se ) { + System.out.println( "fail - setAttributes " + f + " failed: " + se.getMessage() ); + } + + // getAttributes + + int attr; + + if((( attr = f.getAttributes() ) & ATTR_ALL ) == ATTR_ALL ) { + System.out.println( "okay - getAttributes " + f + " successful" ); + } else { + System.out.println( "fail - getAttributes " + f + " failed: 0x" + jcifs.util.Hexdump.toHexString( attr, 4 )); + System.exit( 1 ); + } + + // isHidden - Test to see if the file is hidden + + if( f.isHidden() ) { + System.out.println( "okay - isHidden " + f + " is hidden" ); + } else { + System.out.println( "fail - isHidden " + f + " is not hidden but it should be ... continuing on" ); + } + + // canRead - Test canRead again with both hidden and read-only on + + if( f.canRead() ) { + System.out.println( "okay - canRead " + f + " was successful with read-only and hidden both on" ); + } else { + System.out.println( "fail - canRead " + f + " failed with read-only and hidden both on" ); + } + + // canWrite - Test the file for writing again with read-only and hidden + + if( f.canWrite() ) { + System.out.println( "fail - canWrite " + f + " was successful even though read-only is set ... continuing on" ); + } else { + System.out.println( "okay - canWrite " + f + " failed as it should being that read-only is set" ); + } + + // isDirectory - Test file as a directory + + if( f.isDirectory() ) { + System.out.println( "fail - isDirectory " + f + " returned true but it is NOT a directory" ); + } else { + System.out.println( "okay - isDirectory " + f + " is not a directory" ); + } + + // isDirectory - Test directory as a directory + + if( d.isDirectory() ) { + System.out.println( "okay - isDirectory " + d + " is a directory" ); + } else { + System.out.println( "fail - isDirectory " + d + " returned false but it really is a directory" ); + } + + // isDirectory - Test directory that does not exist + + b = new SmbFile( d, "bogus" ); + + if( b.isDirectory() ) { + System.out.println( "fail - isDirectory " + b + " returned true but it does not exist" ); + } else { + System.out.println( "okay - isDirectory " + b + " does not exist" ); + } + + // isFile - Test file as a file + + if( f.isFile() ) { + System.out.println( "okay - isFile " + f + " is a file" ); + } else { + System.out.println( "fail - isFile " + f + " return false but it is NOT a file" ); + } + + // isFile - Test directory as a file + + if( d.isFile() ) { + System.out.println( "fail - isFile " + d + " returned true but it is NOT a file" ); + } else { + System.out.println( "okay - isFile " + d + " is not a file" ); + } + + // length - Check to ensure that the length of the file is correct + + if( f.length() == 363 ) { + System.out.println( "okay - length " + f + " is correct" ); + } else { + System.out.println( "fail - length " + f + " is wrong: " + f.length() ); + } + + // setReadWrite + + try { + f.setReadWrite(); + System.out.println( "okay - setReadWrite " + f + " successful" ); + } catch( SmbException se ) { + System.out.println( "fail - setReadWrite " + f + " failed: " + se.getMessage() ); + } + + // setLastModified + + long t = (new Date()).getTime() - 1000 * 60; + + try { + f.setLastModified( t ); + System.out.println( "okay - setLastModified " + f + " successful" ); + } catch( SmbException se ) { + System.out.println( "fail - setLastModified " + f + " failed: " + se.getMessage() ); + } + + // lastModified + + if( f.lastModified() == t ) { + System.out.println( "okay - lastModified " + f + " is correct" ); + } else { + System.out.println( "fail - lastModified " + f + " is wrong: " + f.lastModified() + " vs " + t ); + } + + // setCreateTime + + try { + f.setCreateTime( t ); + System.out.println( "okay - setCreateTime " + f + " successful" ); + } catch( SmbException se ) { + System.out.println( "fail - setCreateTime " + f + " failed: " + se.getMessage() ); + } + + // createTime + + if( f.createTime() == t ) { + System.out.println( "okay - createTime " + f + " is correct" ); + } else { + System.out.println( "fail - createTime " + f + " is wrong: " + f.createTime() + " vs " + t ); + } + + // createNewFile + + // delete - See if we can delete the file even though it's read-only + + try { + f.delete(); + System.out.println( "okay - delete " + f + " successful even though the file was read-only" ); + } catch( SmbException se ) { + System.out.println( "fail - delete " + f + " should have turned off the read-only attribute to deleted the file: " + se.getMessage() ); + } + + SmbFile r = new SmbFile( d.getParent(), "JcifsDeleteMe/" ); + + // Must delete any left over directory from a previous run + + try { + r.delete(); + System.out.println( "okay - delete " + r + " successful" ); + } catch( SmbException se ) { + System.out.println( "okay - delete " + r + " probably wasn't there: " + se.getMessage() ); + } + + // renameTo - Rename the whole directory to JcifsDeleteMe + + try { + d.renameTo( r ); + System.out.println( "okay - renameTo " + d + " successful even though it is a directory" ); + } catch( SmbException se ) { + System.out.println( "fail - renameTo " + d + " failed: " + se.getMessage() ); + } + + // delete - Now delete the whole workspace + + try { + r.delete(); + System.out.println( "okay - delete " + r + " successful" ); + } catch( SmbException se ) { + System.out.println( "fail - delete " + r + " failed: " + se.getMessage() ); + } + } +} + diff --git a/examples/FileOpsRenameTo.java b/examples/FileOpsRenameTo.java new file mode 100644 index 0000000..1d2aed2 --- /dev/null +++ b/examples/FileOpsRenameTo.java @@ -0,0 +1,85 @@ +/* Test the following file operations: + * + * canRead + * false - a target that is already open by another process + * false - the target does not exist + * true - the file exists and there are no sharing issues + * canWrite + * true - the file exists and there are no sharing issues + * false - the file is marked read-only + * false - the file does not exist + * delete + * true - the file existed and was succcessfully deleted + * false - the target did not exist + * false - the target is a share, server, workgroup or similar + * false - the target or file under the target directory failed was read-only + * exists + * true - the target, share, IPC share, named pipe, server, or workgroup exists + * false - the opposite of the above + * isDirectory + * true - the target is a workgroup, server, share, or directory + * false - the target is not one of the above or does not exist + * isFile + * direct opposite of isDirectory + * isHidden + * true - target is share ending in $ or marked as hidden + * length + * the file was created to be no larger than ~2G and reports back the size specified + * mkdir + * true - a directory was created successfuly + * false - the directory could not be created + * renameTo + * true - the target was renamed + */ + +import jcifs.smb.*; +import java.io.IOException; +import java.util.Date; + +public class FileOpsRenameTo { + + static final int ATTR_ALL = SmbFile.ATTR_ARCHIVE | SmbFile.ATTR_HIDDEN | SmbFile.ATTR_READONLY | SmbFile.ATTR_SYSTEM; + + public static void main( String argv[] ) throws Exception { + + if( argv.length != 1 ) { + System.out.println( "Must provide an SMB URL of a remote location on which tests will be conducted." ); + System.exit( 1 ); + } + + SmbFile s = new SmbFile( argv[0] ); + SmbFile d = new SmbFile( s, "JcifsTestOpsDir/" ); + + // Create a file to test against + + SmbFile f = null; + try { + f = new SmbFile( d, "foo.txt" ); + SmbFileOutputStream o = new SmbFileOutputStream( f ); + o.write( "The Common Internet File System (CIFS) is the de-facto file sharing protocol on the Microsoft Windows platform. It is the underlying networking protocol used when accessing shares with Windows Explorer, the Network Neighborhood, via a Map Network Drive... dialog, the C:\\> net use * \\\\server\\share commands, or smbclient on UNIX, smbfs on Linux, and elsewhere.\r\n".getBytes() ); + o.close(); + } catch( IOException ioe ) { + System.out.println( "fail - could not create file " + d + "foo.txt: " + ioe.getMessage() ); + } + System.out.println( "okay - created file " + d + "foo.txt" ); + + // renameTo - rename the file to bar.txt + + SmbFile b = new SmbFile( d, "bar.txt" ); + + try { + f.renameTo( b ); + System.out.println( "okay - renameTo " + f + " to " + b + " successful even with read-only" ); + try { + b.renameTo(f); + } catch( SmbException se ) { + System.out.println( "fail - but failed to rename file back to original!" ); + throw se; + } + } catch( SmbException se ) { + se.printStackTrace(); + } + + } +} + diff --git a/examples/FilterFiles.java b/examples/FilterFiles.java new file mode 100644 index 0000000..0d2d815 --- /dev/null +++ b/examples/FilterFiles.java @@ -0,0 +1,36 @@ +import jcifs.netbios.NbtAddress; +import jcifs.smb.*; +import java.util.Date; + +public class FilterFiles { + + static class ShortFilenameFilter implements SmbFilenameFilter { + public boolean accept( SmbFile dir, String name ) throws SmbException { + return name.length() < 14; + } + } + static class BigFileFilter implements SmbFileFilter { + public boolean accept( SmbFile file ) throws SmbException { + return file.length() > 0x1FFFFL; + } + } + + public static void main( String[] argv ) throws Exception { + + SmbFile file = new SmbFile( argv[0] ); + BigFileFilter filter = new BigFileFilter(); + ShortFilenameFilter sfilter = new ShortFilenameFilter(); + DosFileFilter everything = new DosFileFilter( "*", 0xFFFF ); + + long t1 = System.currentTimeMillis(); + SmbFile[] files = file.listFiles( everything ); + long t2 = System.currentTimeMillis() - t1; + + for( int i = 0; i < files.length; i++ ) { + System.out.print( " " + files[i].getName() ); + } + System.out.println(); + System.out.println( files.length + " files in " + t2 + "ms" ); + } +} + diff --git a/examples/Format.java b/examples/Format.java new file mode 100644 index 0000000..941f726 --- /dev/null +++ b/examples/Format.java @@ -0,0 +1,562 @@ +/* + * Cay S. Horstmann & Gary Cornell, Core Java + * Published By Sun Microsystems Press/Prentice-Hall + * Copyright (C) 1997 Sun Microsystems Inc. + * All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for NON-COMMERCIAL purposes + * and without fee is hereby granted provided that this + * copyright notice appears in all copies. + * + * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR + * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS + * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED + * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + */ + +/** + * A class for formatting numbers that follows printf conventions. + * Also implements C-like atoi and atof functions + * @version 1.04 13 Sep 1998 + * @author Cay Horstmann + */ + +import java.io.*; + +public class Format + +{ /** + * Formats the number following printf conventions. + * Main limitation: Can only handle one format parameter at a time + * Use multiple Format objects to format more than one number + * @param s the format string following printf conventions + * The string has a prefix, a format code and a suffix. The prefix and suffix + * become part of the formatted output. The format code directs the + * formatting of the (single) parameter to be formatted. The code has the + * following structure + *
    + *
  • a % (required) + *
  • a modifier (optional) + *
    + *
    +
    forces display of + for positive numbers + *
    0
    show leading zeroes + *
    -
    align left in the field + *
    space
    prepend a space in front of positive numbers + *
    #
    use "alternate" format. Add 0 or 0x for octal or hexadecimal numbers. Don't suppress trailing zeroes in general floating point format. + *
    + *
  • an integer denoting field width (optional) + *
  • a period followed by an integer denoting precision (optional) + *
  • a format descriptor (required) + *
    + *
    f
    floating point number in fixed format + *
    e, E
    floating point number in exponential notation (scientific format). The E format results in an uppercase E for the exponent (1.14130E+003), the e format in a lowercase e. + *
    g, G
    floating point number in general format (fixed format for small numbers, exponential format for large numbers). Trailing zeroes are suppressed. The G format results in an uppercase E for the exponent (if any), the g format in a lowercase e. + *
    d, i
    integer in decimal + *
    x
    integer in hexadecimal + *
    o
    integer in octal + *
    s
    string + *
    c
    character + *
    + *
+ * @exception IllegalArgumentException if bad format + */ + + public Format(String s) + { width = 0; + precision = -1; + pre = ""; + post = ""; + leading_zeroes = false; + show_plus = false; + alternate = false; + show_space = false; + left_align = false; + fmt = ' '; + + int state = 0; + int length = s.length(); + int parse_state = 0; + // 0 = prefix, 1 = flags, 2 = width, 3 = precision, + // 4 = format, 5 = end + int i = 0; + + while (parse_state == 0) + { if (i >= length) parse_state = 5; + else if (s.charAt(i) == '%') + { if (i < length - 1) + { if (s.charAt(i + 1) == '%') + { pre = pre + '%'; + i++; + } + else + parse_state = 1; + } + else throw new java.lang.IllegalArgumentException(); + } + else + pre = pre + s.charAt(i); + i++; + } + while (parse_state == 1) + { if (i >= length) parse_state = 5; + else if (s.charAt(i) == ' ') show_space = true; + else if (s.charAt(i) == '-') left_align = true; + else if (s.charAt(i) == '+') show_plus = true; + else if (s.charAt(i) == '0') leading_zeroes = true; + else if (s.charAt(i) == '#') alternate = true; + else { parse_state = 2; i--; } + i++; + } + while (parse_state == 2) + { if (i >= length) parse_state = 5; + else if ('0' <= s.charAt(i) && s.charAt(i) <= '9') + { width = width * 10 + s.charAt(i) - '0'; + i++; + } + else if (s.charAt(i) == '.') + { parse_state = 3; + precision = 0; + i++; + } + else + parse_state = 4; + } + while (parse_state == 3) + { if (i >= length) parse_state = 5; + else if ('0' <= s.charAt(i) && s.charAt(i) <= '9') + { precision = precision * 10 + s.charAt(i) - '0'; + i++; + } + else + parse_state = 4; + } + if (parse_state == 4) + { if (i >= length) parse_state = 5; + else fmt = s.charAt(i); + i++; + } + if (i < length) + post = s.substring(i, length); + } + + /** + * prints a formatted number following printf conventions + * @param s a PrintStream + * @param fmt the format string + * @param x the double to print + */ + + public static void print(java.io.PrintStream s, String fmt, double x) + { s.print(new Format(fmt).form(x)); + } + + /** + * prints a formatted number following printf conventions + * @param s a PrintStream + * @param fmt the format string + * @param x the long to print + */ + public static void print(java.io.PrintStream s, String fmt, long x) + { s.print(new Format(fmt).form(x)); + } + + /** + * prints a formatted number following printf conventions + * @param s a PrintStream + * @param fmt the format string + * @param x the character to + */ + + public static void print(java.io.PrintStream s, String fmt, char x) + { s.print(new Format(fmt).form(x)); + } + + /** + * prints a formatted number following printf conventions + * @param s a PrintStream, fmt the format string + * @param x a string that represents the digits to print + */ + + public static void print(java.io.PrintStream s, String fmt, String x) + { s.print(new Format(fmt).form(x)); + } + + /** + * Converts a string of digits (decimal, octal or hex) to an integer + * @param s a string + * @return the numeric value of the prefix of s representing a base 10 integer + */ + + public static int atoi(String s) + { return (int)atol(s); + } + + /** + * Converts a string of digits (decimal, octal or hex) to a long integer + * @param s a string + * @return the numeric value of the prefix of s representing a base 10 integer + */ + + public static long atol(String s) + { int i = 0; + + while (i < s.length() && Character.isWhitespace(s.charAt(i))) i++; + if (i < s.length() && s.charAt(i) == '0') + { if (i + 1 < s.length() && (s.charAt(i + 1) == 'x' || s.charAt(i + 1) == 'X')) + return parseLong(s.substring(i + 2), 16); + else return parseLong(s, 8); + } + else return parseLong(s, 10); + } + + private static long parseLong(String s, int base) + { int i = 0; + int sign = 1; + long r = 0; + + while (i < s.length() && Character.isWhitespace(s.charAt(i))) i++; + if (i < s.length() && s.charAt(i) == '-') { sign = -1; i++; } + else if (i < s.length() && s.charAt(i) == '+') { i++; } + while (i < s.length()) + { char ch = s.charAt(i); + if ('0' <= ch && ch < '0' + base) + r = r * base + ch - '0'; + else if ('A' <= ch && ch < 'A' + base - 10) + r = r * base + ch - 'A' + 10 ; + else if ('a' <= ch && ch < 'a' + base - 10) + r = r * base + ch - 'a' + 10 ; + else + return r * sign; + i++; + } + return r * sign; + } + + /** + * Converts a string of digits to an double + * @param s a string + */ + + public static double atof(String s) + { int i = 0; + int sign = 1; + double r = 0; // integer part + double f = 0; // fractional part + double p = 1; // exponent of fractional part + int state = 0; // 0 = int part, 1 = frac part + + while (i < s.length() && Character.isWhitespace(s.charAt(i))) i++; + if (i < s.length() && s.charAt(i) == '-') { sign = -1; i++; } + else if (i < s.length() && s.charAt(i) == '+') { i++; } + while (i < s.length()) + { char ch = s.charAt(i); + if ('0' <= ch && ch <= '9') + { if (state == 0) + r = r * 10 + ch - '0'; + else if (state == 1) + { p = p / 10; + r = r + p * (ch - '0'); + } + } + else if (ch == '.') + { if (state == 0) state = 1; + else return sign * r; + } + else if (ch == 'e' || ch == 'E') + { long e = (int)parseLong(s.substring(i + 1), 10); + return sign * r * Math.pow(10, e); + } + else return sign * r; + i++; + } + return sign * r; + } + + /** + * Formats a double into a string (like sprintf in C) + * @param x the number to format + * @return the formatted string + * @exception IllegalArgumentException if bad argument + */ + + public String form(double x) + { String r; + if (precision < 0) precision = 6; + int s = 1; + if (x < 0) { x = -x; s = -1; } + if (fmt == 'f') + r = fixed_format(x); + else if (fmt == 'e' || fmt == 'E' || fmt == 'g' || fmt == 'G') + r = exp_format(x); + else throw new java.lang.IllegalArgumentException(); + + return pad(sign(s, r)); + } + + /** + * Formats a long integer into a string (like sprintf in C) + * @param x the number to format + * @return the formatted string + */ + + public String form(long x) + { String r; + int s = 0; + if (fmt == 'd' || fmt == 'i') + { if (x < 0) + { r = ("" + x).substring(1); + s = -1; + } + else + { r = "" + x; + s = 1; + } + } + else if (fmt == 'o') + r = convert(x, 3, 7, "01234567"); + else if (fmt == 'x') + r = convert(x, 4, 15, "0123456789abcdef"); + else if (fmt == 'X') + r = convert(x, 4, 15, "0123456789ABCDEF"); + else throw new java.lang.IllegalArgumentException(); + + return pad(sign(s, r)); + } + + /** + * Formats a character into a string (like sprintf in C) + * @param x the value to format + * @return the formatted string + */ + + public String form(char c) + { if (fmt != 'c') + throw new java.lang.IllegalArgumentException(); + + String r = "" + c; + return pad(r); + } + + /** + * Formats a string into a larger string (like sprintf in C) + * @param x the value to format + * @return the formatted string + */ + + public String form(String s) + { if (fmt != 's') + throw new java.lang.IllegalArgumentException(); + if (precision >= 0 && precision < s.length()) + s = s.substring(0, precision); + return pad(s); + } + + + /** + * a test stub for the format class + */ + + public static void main(String[] a) + { double x = 1.23456789012; + double y = 123; + double z = 1.2345e30; + double w = 1.02; + double u = 1.234e-5; + int d = 0xCAFE; + Format.print(System.out, "x = |%f|\n", x); + Format.print(System.out, "u = |%20f|\n", u); + Format.print(System.out, "x = |% .5f|\n", x); + Format.print(System.out, "w = |%20.5f|\n", w); + Format.print(System.out, "x = |%020.5f|\n", x); + Format.print(System.out, "x = |%+20.5f|\n", x); + Format.print(System.out, "x = |%+020.5f|\n", x); + Format.print(System.out, "x = |% 020.5f|\n", x); + Format.print(System.out, "y = |%#+20.5f|\n", y); + Format.print(System.out, "y = |%-+20.5f|\n", y); + Format.print(System.out, "z = |%20.5f|\n", z); + + Format.print(System.out, "x = |%e|\n", x); + Format.print(System.out, "u = |%20e|\n", u); + Format.print(System.out, "x = |% .5e|\n", x); + Format.print(System.out, "w = |%20.5e|\n", w); + Format.print(System.out, "x = |%020.5e|\n", x); + Format.print(System.out, "x = |%+20.5e|\n", x); + Format.print(System.out, "x = |%+020.5e|\n", x); + Format.print(System.out, "x = |% 020.5e|\n", x); + Format.print(System.out, "y = |%#+20.5e|\n", y); + Format.print(System.out, "y = |%-+20.5e|\n", y); + + Format.print(System.out, "x = |%g|\n", x); + Format.print(System.out, "z = |%g|\n", z); + Format.print(System.out, "w = |%g|\n", w); + Format.print(System.out, "u = |%g|\n", u); + Format.print(System.out, "y = |%.2g|\n", y); + Format.print(System.out, "y = |%#.2g|\n", y); + + Format.print(System.out, "d = |%d|\n", d); + Format.print(System.out, "d = |%20d|\n", d); + Format.print(System.out, "d = |%020d|\n", d); + Format.print(System.out, "d = |%+20d|\n", d); + Format.print(System.out, "d = |% 020d|\n", d); + Format.print(System.out, "d = |%-20d|\n", d); + Format.print(System.out, "d = |%20.8d|\n", d); + Format.print(System.out, "d = |%x|\n", d); + Format.print(System.out, "d = |%20X|\n", d); + Format.print(System.out, "d = |%#20x|\n", d); + Format.print(System.out, "d = |%020X|\n", d); + Format.print(System.out, "d = |%20.8x|\n", d); + Format.print(System.out, "d = |%o|\n", d); + Format.print(System.out, "d = |%020o|\n", d); + Format.print(System.out, "d = |%#20o|\n", d); + Format.print(System.out, "d = |%#020o|\n", d); + Format.print(System.out, "d = |%20.12o|\n", d); + + Format.print(System.out, "s = |%-20s|\n", "Hello"); + Format.print(System.out, "s = |%-20c|\n", '!'); + + // regression test to confirm fix of reported bugs + + Format.print(System.out, "|%i|\n", Long.MIN_VALUE); + + Format.print(System.out, "|%6.2e|\n", 0.0); + Format.print(System.out, "|%6.2g|\n", 0.0); + + Format.print(System.out, "|%6.2f|\n", 9.99); + Format.print(System.out, "|%6.2f|\n", 9.999); + + Format.print(System.out, "|%6.0f|\n", 9.999); + } + + private static String repeat(char c, int n) + { if (n <= 0) return ""; + StringBuffer s = new StringBuffer(n); + for (int i = 0; i < n; i++) s.append(c); + return s.toString(); + } + + private static String convert(long x, int n, int m, String d) + { if (x == 0) return "0"; + String r = ""; + while (x != 0) + { r = d.charAt((int)(x & m)) + r; + x = x >>> n; + } + return r; + } + + private String pad(String r) + { String p = repeat(' ', width - r.length()); + if (left_align) return pre + r + p + post; + else return pre + p + r + post; + } + + private String sign(int s, String r) + { String p = ""; + if (s < 0) p = "-"; + else if (s > 0) + { if (show_plus) p = "+"; + else if (show_space) p = " "; + } + else + { if (fmt == 'o' && alternate && r.length() > 0 && r.charAt(0) != '0') p = "0"; + else if (fmt == 'x' && alternate) p = "0x"; + else if (fmt == 'X' && alternate) p = "0X"; + } + int w = 0; + if (leading_zeroes) + w = width; + else if ((fmt == 'd' || fmt == 'i' || fmt == 'x' || fmt == 'X' || fmt == 'o') + && precision > 0) w = precision; + + return p + repeat('0', w - p.length() - r.length()) + r; + } + + private String fixed_format(double d) + { boolean removeTrailing + = (fmt == 'G' || fmt == 'g') && !alternate; + // remove trailing zeroes and decimal point + + if (d > 0x7FFFFFFFFFFFFFFFL) return exp_format(d); + if (precision == 0) + return (long)(d + 0.5) + (removeTrailing ? "" : "."); + + long whole = (long)d; + double fr = d - whole; // fractional part + if (fr >= 1 || fr < 0) return exp_format(d); + + double factor = 1; + String leading_zeroes = ""; + for (int i = 1; i <= precision && factor <= 0x7FFFFFFFFFFFFFFFL; i++) + { factor *= 10; + leading_zeroes = leading_zeroes + "0"; + } + long l = (long) (factor * fr + 0.5); + if (l >= factor) { l = 0; whole++; } // CSH 10-25-97 + + String z = leading_zeroes + l; + z = "." + z.substring(z.length() - precision, z.length()); + + if (removeTrailing) + { int t = z.length() - 1; + while (t >= 0 && z.charAt(t) == '0') t--; + if (t >= 0 && z.charAt(t) == '.') t--; + z = z.substring(0, t + 1); + } + + return whole + z; + } + + private String exp_format(double d) + { String f = ""; + int e = 0; + double dd = d; + double factor = 1; + if (d != 0) + { while (dd > 10) { e++; factor /= 10; dd = dd / 10; } + while (dd < 1) { e--; factor *= 10; dd = dd * 10; } + } + if ((fmt == 'g' || fmt == 'G') && e >= -4 && e < precision) + return fixed_format(d); + + d = d * factor; + f = f + fixed_format(d); + + if (fmt == 'e' || fmt == 'g') + f = f + "e"; + else + f = f + "E"; + + String p = "000"; + if (e >= 0) + { f = f + "+"; + p = p + e; + } + else + { f = f + "-"; + p = p + (-e); + } + + return f + p.substring(p.length() - 3, p.length()); + } + + private int width; + private int precision; + private String pre; + private String post; + private boolean leading_zeroes; + private boolean show_plus; + private boolean alternate; + private boolean show_space; + private boolean left_align; + private char fmt; // one of cdeEfgGiosxXos +} + + + + + diff --git a/examples/Get.java b/examples/Get.java new file mode 100644 index 0000000..a03b524 --- /dev/null +++ b/examples/Get.java @@ -0,0 +1,33 @@ +import jcifs.smb.SmbFile; +import jcifs.smb.SmbFileInputStream; +import java.io.FileOutputStream; + +public class Get { + + public static void main( String argv[] ) throws Exception { + + SmbFile f = new SmbFile( argv[0] ); + SmbFileInputStream in = new SmbFileInputStream( f ); + FileOutputStream out = new FileOutputStream( f.getName() ); + + long t0 = System.currentTimeMillis(); + + byte[] b = new byte[8192]; + int n, tot = 0; + long t1 = t0; + while(( n = in.read( b )) > 0 ) { + out.write( b, 0, n ); + tot += n; + System.out.print( '#' ); + } + + long t = System.currentTimeMillis() - t0; + + System.out.println(); + System.out.println( tot + " bytes transfered in " + ( t / 1000 ) + " seconds at " + (( tot / 1000 ) / Math.max( 1, ( t / 1000 ))) + "Kbytes/sec" ); + + in.close(); + out.close(); + } +} + diff --git a/examples/GetDate.java b/examples/GetDate.java new file mode 100644 index 0000000..fc42ea7 --- /dev/null +++ b/examples/GetDate.java @@ -0,0 +1,16 @@ +import java.util.Date; +import jcifs.smb.SmbFile; +import java.text.SimpleDateFormat; +import java.util.GregorianCalendar; + +public class GetDate { + + public static void main( String argv[] ) throws Exception { + SmbFile f = new SmbFile( argv[0] ); + Date d = new Date( f.lastModified() ); + SimpleDateFormat sdf = new SimpleDateFormat( "EEEE, MMMM d, yyyy h:mm:ss a" ); + sdf.setCalendar( new GregorianCalendar() ); + System.out.println( sdf.format( d )); + } +} + diff --git a/examples/GetDfsPath.java b/examples/GetDfsPath.java new file mode 100644 index 0000000..6db7362 --- /dev/null +++ b/examples/GetDfsPath.java @@ -0,0 +1,11 @@ +import jcifs.smb.SmbFile; + +public class GetDfsPath { + + public static void main( String argv[] ) throws Exception { + + SmbFile f = new SmbFile( argv[0] ); + System.out.println( f.getDfsPath() ); + } +} + diff --git a/examples/GetGroupMemberSids.java b/examples/GetGroupMemberSids.java new file mode 100644 index 0000000..b44c20d --- /dev/null +++ b/examples/GetGroupMemberSids.java @@ -0,0 +1,25 @@ +import java.util.*; +import jcifs.smb.*; + +public class GetGroupMemberSids { + + public static void main( String[] argv ) throws Exception { + if (argv.length < 2) { + System.err.println("usage: GetGroupMemberSids "); + System.exit(1); + } + + SmbFile file = new SmbFile(argv[0]); + SID sid = new SID(argv[1]); + + String server = file.getServer(); + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)file.getPrincipal(); + + SID[] mems = sid.getGroupMemberSids(server, auth, SID.SID_FLAG_RESOLVE_SIDS); + + for (int mi = 0; mi < mems.length; mi++) { + SID mem = mems[mi]; + System.out.println(mem.getType() + " " + mem.toDisplayString()); + } + } +} diff --git a/examples/GetGroupMemberSidsFromURL.java b/examples/GetGroupMemberSidsFromURL.java new file mode 100644 index 0000000..7ad1f32 --- /dev/null +++ b/examples/GetGroupMemberSidsFromURL.java @@ -0,0 +1,34 @@ +import java.util.*; +import jcifs.smb.*; + +public class GetGroupMemberSidsFromURL { + + public static void main( String[] argv ) throws Exception { + if (argv.length < 1) { + System.err.println("usage: GetGroupMemberSidsFromURL "); + System.exit(1); + } + + SmbFile file = new SmbFile(argv[0]); + String server = file.getServer(); + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)file.getPrincipal(); + ACE[] security = file.getSecurity(true); + + for (int ai = 0; ai < security.length; ai++) { + ACE ace = security[ai]; + SID sid = ace.getSID(); + if (sid.equals(SID.EVERYONE) || + sid.equals(SID.CREATOR_OWNER) || + sid.equals(SID.SYSTEM)) + continue; + + System.out.println(sid.toString() + " (" + sid.toDisplayString() + ") members:"); + + SID[] mems = sid.getGroupMemberSids(server, auth, SID.SID_FLAG_RESOLVE_SIDS); + for (int mi = 0; mi < mems.length; mi++) { + SID mem = mems[mi]; + System.out.println(" " + mem.getType() + " " + mem.toDisplayString()); + } + } + } +} diff --git a/examples/GetLocalGroupMemberSidsFromURL.java b/examples/GetLocalGroupMemberSidsFromURL.java new file mode 100644 index 0000000..418ee00 --- /dev/null +++ b/examples/GetLocalGroupMemberSidsFromURL.java @@ -0,0 +1,34 @@ +import java.util.*; +import jcifs.smb.*; + +public class GetLocalGroupMemberSidsFromURL { + + public static void main( String[] argv ) throws Exception { + if (argv.length < 1) { + System.err.println("usage: GetLocalGroupMemberSidsFromURL "); + System.exit(1); + } + + SmbFile file = new SmbFile(argv[0]); + String server = file.getServer(); + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)file.getPrincipal(); + ACE[] security = file.getSecurity(true); + + SID serverSid = SID.getServerSid(server, auth); + + for (int ai = 0; ai < security.length; ai++) { + ACE ace = security[ai]; + SID sid = ace.getSID(); + + if (sid.getType() == SID.SID_TYPE_ALIAS && serverSid.equals(sid.getDomainSid())) { + System.out.println(sid.toString() + " (" + sid.toDisplayString() + ") members:"); + + SID[] mems = sid.getGroupMemberSids(server, auth, SID.SID_FLAG_RESOLVE_SIDS); + for (int mi = 0; mi < mems.length; mi++) { + SID mem = mems[mi]; + System.out.println(" " + mem.getType() + " " + mem.toDisplayString()); + } + } + } + } +} diff --git a/examples/GetLocalGroupsMap.java b/examples/GetLocalGroupsMap.java new file mode 100644 index 0000000..0dc702d --- /dev/null +++ b/examples/GetLocalGroupsMap.java @@ -0,0 +1,30 @@ +import java.util.*; +import jcifs.smb.*; + +public class GetLocalGroupsMap { + + public static void main( String[] argv ) throws Exception { + + SmbFile file = new SmbFile(argv[0]); + String server = file.getServer(); + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)file.getPrincipal(); + Map map = SID.getLocalGroupsMap(server, + auth, + SID.SID_FLAG_RESOLVE_SIDS); + + + Iterator kiter = map.keySet().iterator(); + while (kiter.hasNext()) { + SID userSid = (SID)kiter.next(); + + System.out.println(userSid.getType() + " " + userSid.toDisplayString() + ":"); + + ArrayList groupSids = (ArrayList)map.get(userSid); + Iterator giter = groupSids.iterator(); + while (giter.hasNext()) { + SID group = (SID)giter.next(); + System.out.println(" " + group.getType() + " " + group.toDisplayString()); + } + } + } +} diff --git a/examples/GetSecurity.java b/examples/GetSecurity.java new file mode 100644 index 0000000..b997419 --- /dev/null +++ b/examples/GetSecurity.java @@ -0,0 +1,14 @@ +import jcifs.smb.*; + +public class GetSecurity { + + public static void main( String[] argv ) throws Exception { + + SmbFile file = new SmbFile( argv[0] ); + ACE[] security = file.getSecurity(true); + + for (int ai = 0; ai < security.length; ai++) { + System.out.println(security[ai].toString()); + } + } +} diff --git a/examples/GetServerSidFromURL.java b/examples/GetServerSidFromURL.java new file mode 100644 index 0000000..ce0b516 --- /dev/null +++ b/examples/GetServerSidFromURL.java @@ -0,0 +1,20 @@ +import java.util.*; +import jcifs.smb.*; + +public class GetServerSidFromURL { + + public static void main( String[] argv ) throws Exception { + if (argv.length < 1) { + System.err.println("usage: GetServerSidFromURL "); + System.exit(1); + } + + SmbFile file = new SmbFile(argv[0]); + String server = file.getServer(); + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)file.getPrincipal(); + + SID serverSid = SID.getServerSid(server, auth); + + System.out.println(serverSid); + } +} diff --git a/examples/GetShareSecurity.java b/examples/GetShareSecurity.java new file mode 100644 index 0000000..7ede8d5 --- /dev/null +++ b/examples/GetShareSecurity.java @@ -0,0 +1,20 @@ +import jcifs.smb.*; + +public class GetShareSecurity { + + public static void main( String[] argv ) throws Exception { + SmbFile file = new SmbFile( argv[0] ); + ACE[] security; + + security = file.getShareSecurity(true); + System.out.println("Share Permissions:"); + for (int ai = 0; ai < security.length; ai++) { + System.out.println(security[ai].toString()); + } + System.out.println("Security:"); + security = file.getSecurity(true); + for (int ai = 0; ai < security.length; ai++) { + System.out.println(security[ai].toString()); + } + } +} diff --git a/examples/GetType.java b/examples/GetType.java new file mode 100644 index 0000000..c0a9b9e --- /dev/null +++ b/examples/GetType.java @@ -0,0 +1,53 @@ +import jcifs.netbios.NbtAddress; +import jcifs.smb.SmbFile; +import java.util.Date; + +public class GetType { + + static final String[] types = { "TYPE_FILESYSTEM", "TYPE_WORKGROUP", + "TYPE_SERVER", "TYPE_SHARE", "TYPE_NAMED_PIPE", "TYPE_PRINTER", "TYPE_COMM" }; + + public static void main( String[] argv ) throws Exception { + + SmbFile file = new SmbFile( argv[0] ); + int type; + + switch( file.getType() ) { + case SmbFile.TYPE_FILESYSTEM: + type = 0; + break; + case SmbFile.TYPE_WORKGROUP: + type = 1; + break; + case SmbFile.TYPE_SERVER: + type = 2; + break; + case SmbFile.TYPE_SHARE: + type = 3; + break; + case SmbFile.TYPE_NAMED_PIPE: + type = 4; + break; + case SmbFile.TYPE_PRINTER: + type = 5; + break; + case SmbFile.TYPE_COMM: + type = 6; + break; + default: + throw new RuntimeException( "Unknown service type: " + file.getType() ); + } + System.out.println( types[type] ); + System.out.println(); + + long t1 = System.currentTimeMillis(); + String[] files = file.list(); + long t2 = System.currentTimeMillis() - t1; + + for( int i = 0; i < files.length; i++ ) { + System.out.print( " " + files[i] ); + } + System.out.println(); + System.out.println( files.length + " files in " + t2 + "ms" ); + } +} diff --git a/examples/GetURL.java b/examples/GetURL.java new file mode 100644 index 0000000..c1529e3 --- /dev/null +++ b/examples/GetURL.java @@ -0,0 +1,25 @@ +import java.net.URL; +import java.io.InputStream; + +public class GetURL { + + public static void main( String argv[] ) throws Exception { + + jcifs.Config.registerSmbURLHandler(); + + URL url = new URL( argv[0] ); + InputStream in = url.openStream(); + + if( in != null ) { + byte[] buf = new byte[4096]; + int n; + while(( n = in.read( buf )) != -1 ) { + System.out.write( buf, 0, n ); + } + } else { + System.out.println( "stream waz null" ); + } + in.close(); + } +} + diff --git a/examples/GrowWrite.java b/examples/GrowWrite.java new file mode 100644 index 0000000..e3e6a78 --- /dev/null +++ b/examples/GrowWrite.java @@ -0,0 +1,30 @@ +import jcifs.smb.SmbFile; +import jcifs.smb.SmbFileOutputStream; +import java.io.FileInputStream; + +public class GrowWrite { + + static final int SIZE = 0xFFF; + + public static void main( String argv[] ) throws Exception { + int n, tot; + byte[] buf = new byte[SIZE]; + SmbFile f = new SmbFile( argv[0] ); + SmbFileOutputStream out = new SmbFileOutputStream( f ); + + n = tot = 0; + do { + if(( n % 0x1F ) == 0) { + f = new SmbFile( argv[0] ); + out = new SmbFileOutputStream( f ); + System.out.print( '#' ); + } + out.write( buf, 0, n ); + out.flush(); + tot += n; + } while( n++ < SIZE ); + + System.out.println(); + System.out.println( tot + " bytes transfered." ); + } +} diff --git a/examples/HttpURL.java b/examples/HttpURL.java new file mode 100644 index 0000000..6a2465d --- /dev/null +++ b/examples/HttpURL.java @@ -0,0 +1,11 @@ +import java.net.*; + +public class HttpURL { + + public static void main( String[] args ) throws Exception { + jcifs.Config.registerSmbURLHandler(); + + URL u = new URL( new URL( args[0] ), args[1] ); + System.out.println( u ); + } +} diff --git a/examples/Interleave.java b/examples/Interleave.java new file mode 100644 index 0000000..6960acb --- /dev/null +++ b/examples/Interleave.java @@ -0,0 +1,40 @@ +import jcifs.smb.*; + +public class Interleave { + + static class IThread extends Thread { + String url; + + IThread( String url ) { + this.url = url; + } + + public void run() { + try { + yield(); + System.out.println( getName() + ": started" ); + SmbFileOutputStream o = new SmbFileOutputStream( url ); + o.close(); + System.out.println( getName() + ": done" ); + } catch( Exception x ) { + x.printStackTrace(); + } + } + } + + public static void main(String[] argv) throws Exception { + if( argv.length < 2 ) { + System.out.println( "java Interleave dir numThreads" ); + return; + } + + int numThreads = Integer.parseInt( argv[1] ); + IThread[] t = new IThread[numThreads]; + for( int i = 0; i < numThreads; i++ ) { + t[i] = new IThread( argv[0] + "/it" + i + ".tmp" ); + } + for( int j = 0; j < numThreads; j++ ) { + t[j].start(); + } + } +} diff --git a/examples/InterruptTest.java b/examples/InterruptTest.java new file mode 100644 index 0000000..a35d2be --- /dev/null +++ b/examples/InterruptTest.java @@ -0,0 +1,54 @@ +import java.io.InterruptedIOException; +import jcifs.util.transport.TransportException; +import jcifs.smb.*; + +public class InterruptTest extends Thread { + + String url; + + public InterruptTest(String url) { + this.url = url; + } + public void run() { + for (int i = 0; i < 100; i++) { + try { + SmbFileInputStream in = new SmbFileInputStream(url); + + byte[] b = new byte[10]; + while(in.read( b ) > 0) { + ; + } + + in.close(); + } catch(InterruptedIOException iioe) { + System.out.println("InterruptedIOException"); + continue; + } catch(SmbException se) { + Throwable t = se.getRootCause(); + if (t instanceof TransportException) { + TransportException te = (TransportException)t; + t = te.getRootCause(); + if (t instanceof InterruptedException) { + System.out.println("InterruptedException in constructor"); + continue; + } + } + se.printStackTrace(); + try { Thread.sleep(500); } catch(InterruptedException ie) {} + } catch(Exception e) { + e.printStackTrace(); + break; + } + } + } + + public static void main( String argv[] ) throws Exception { + InterruptTest it = new InterruptTest(argv[0]); + it.start(); + for (int i = 0; i < 20; i++) { + Thread.sleep(200); + it.interrupt(); + } + } +} + diff --git a/examples/IsDir.java b/examples/IsDir.java new file mode 100644 index 0000000..d8f41e2 --- /dev/null +++ b/examples/IsDir.java @@ -0,0 +1,10 @@ +import jcifs.smb.SmbFile; + +public class IsDir { + + public static void main( String argv[] ) throws Exception { + SmbFile f = new SmbFile( argv[0] ); + System.out.println( f.isDirectory() ); + } +} + diff --git a/examples/LargeListFiles.java b/examples/LargeListFiles.java new file mode 100644 index 0000000..1ad7db7 --- /dev/null +++ b/examples/LargeListFiles.java @@ -0,0 +1,39 @@ +import jcifs.netbios.NbtAddress; +import jcifs.smb.*; +import java.util.Date; + +public class LargeListFiles extends DosFileFilter { + + int count = 0; + + public LargeListFiles() { + super("*", 0xFFFF); + } + public LargeListFiles(String wildcard, int attributes) { + super(wildcard, attributes); + } + + public boolean accept(SmbFile file) throws SmbException { + System.out.print( " " + file.getName() ); + count++; + return false; /* file processed here, tell listFiles() to discard */ + } + + public static void main( String[] argv ) throws Exception { + if (argv.length < 1) { + System.err.println("usage: LargeListFiles \n"); + System.exit(1); + } + + SmbFile file = new SmbFile( argv[0] ); + LargeListFiles llf = new LargeListFiles(); + + long t1 = System.currentTimeMillis(); + file.listFiles(llf); + long t2 = System.currentTimeMillis() - t1; + + System.out.println(); + System.out.println( llf.count + " files in " + t2 + "ms" ); + } +} + diff --git a/examples/Length.java b/examples/Length.java new file mode 100644 index 0000000..7b1d5cd --- /dev/null +++ b/examples/Length.java @@ -0,0 +1,11 @@ +import jcifs.smb.SmbFile; + +public class Length { + + public static void main( String argv[] ) throws Exception { + + SmbFile f = new SmbFile( argv[0] ); + System.out.println( argv[0] + "'s length is " + f.length() ); + } +} + diff --git a/examples/List.java b/examples/List.java new file mode 100644 index 0000000..b4a1304 --- /dev/null +++ b/examples/List.java @@ -0,0 +1,21 @@ +import jcifs.netbios.NbtAddress; +import jcifs.smb.SmbFile; +import java.util.Date; + +public class List { + + public static void main( String[] argv ) throws Exception { + + SmbFile file = new SmbFile( argv[0] ); + + long t1 = System.currentTimeMillis(); + String[] files = file.list(); + long t2 = System.currentTimeMillis() - t1; + + for( int i = 0; i < files.length; i++ ) { + System.out.print( " " + files[i] ); + } + System.out.println(); + System.out.println( files.length + " files in " + t2 + "ms" ); + } +} diff --git a/examples/ListACL.java b/examples/ListACL.java new file mode 100644 index 0000000..a654276 --- /dev/null +++ b/examples/ListACL.java @@ -0,0 +1,23 @@ +import jcifs.smb.*; + +public class ListACL { + + public static void main( String[] args ) throws Exception { + if (args.length < 1) { + System.err.println( "usage: ListACL \n" ); + return; + } + SmbFile f = new SmbFile( args[0] ); + ACE[] acl = f.getSecurity(); + for (int i = 0; i < acl.length; i++) { + System.out.println( acl[i] ); + SID sid = acl[i].getSID(); + System.out.println(" toString: " + sid.toString()); + System.out.println(" toSidString: " + sid.toDisplayString()); + System.out.println(" getType: " + sid.getType()); + System.out.println(" getTypeText: " + sid.getTypeText()); + System.out.println(" getDomainName: " + sid.getDomainName()); + System.out.println("getAccountName: " + sid.getAccountName()); + } + } +} diff --git a/examples/ListFiles.java b/examples/ListFiles.java new file mode 100644 index 0000000..b104487 --- /dev/null +++ b/examples/ListFiles.java @@ -0,0 +1,30 @@ +import jcifs.netbios.NbtAddress; +import jcifs.smb.SmbFile; +import java.util.Date; + +public class ListFiles { + + public static void main( String[] argv ) throws Exception { + + for (int a = 0; a < argv.length; a++) { + SmbFile file; + SmbFile[] files = new SmbFile[0]; + + file = new SmbFile( argv[a] ); + + long t1 = System.currentTimeMillis(); + try { + files = file.listFiles(); + } catch (Exception e) { + e.printStackTrace(); + } + long t2 = System.currentTimeMillis() - t1; + + for( int i = 0; i < files.length; i++ ) { + System.out.print( " " + files[i].getName() ); + } + System.out.println(); + System.out.println( files.length + " files in " + t2 + "ms" ); + } + } +} diff --git a/examples/ListTypes.java b/examples/ListTypes.java new file mode 100644 index 0000000..b169eca --- /dev/null +++ b/examples/ListTypes.java @@ -0,0 +1,43 @@ +import jcifs.netbios.NbtAddress; +import jcifs.smb.SmbFile; +import java.util.Date; + +public class ListTypes { + + public static void main( String[] argv ) throws Exception { + + SmbFile file = new SmbFile( argv[0] ); + + long t1 = System.currentTimeMillis(); + SmbFile[] files = file.listFiles(); + long t2 = System.currentTimeMillis() - t1; + + for( int i = 0; i < files.length; i++ ) { + System.out.print( " " + files[i].getName() ); + switch(files[i].getType()) { + case SmbFile.TYPE_FILESYSTEM: + System.out.println( "[TYPE_FILESYSTEM]" ); + break; + case SmbFile.TYPE_WORKGROUP: + System.out.println( "[TYPE_WORKGROUP]" ); + break; + case SmbFile.TYPE_SERVER: + System.out.println( "[TYPE_SERVER]" ); + break; + case SmbFile.TYPE_SHARE: + System.out.println( "[TYPE_SHARE]" ); + break; + case SmbFile.TYPE_NAMED_PIPE: + System.out.println( "[TYPE_NAMEDPIPE]" ); + break; + case SmbFile.TYPE_PRINTER: + System.out.println( "[TYPE_PRINTER]" ); + break; + case SmbFile.TYPE_COMM: + System.out.println( "[TYPE_COMM]" ); + break; + }; + } + System.out.println( files.length + " files in " + t2 + "ms" ); + } +} diff --git a/examples/Logon.java b/examples/Logon.java new file mode 100644 index 0000000..eacef0d --- /dev/null +++ b/examples/Logon.java @@ -0,0 +1,15 @@ +import jcifs.*; +import jcifs.smb.*; + +public class Logon { + + /* java Logon 192.168.1.15 "dom;user:pass" + */ + + public static void main( String argv[] ) throws Exception { + UniAddress dc = UniAddress.getByName( argv[0] ); + NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication( argv[1] ); + SmbSession.logon( dc, auth ); + } +} + diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000..35e6c0a --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,14 @@ +JAVA_HOME=/usr/local/java4 +CLASSPATH=../build:. + +.SUFFIXES: .java .class + +CLASSFILES=GetGroupMemberSidsFromURL.class ListACL.class LargeListFiles.class GetShareSecurity.class CountPerms.class AclCrawler.class SidCacheTest.class GetSecurity.class SidCrawler.class InterruptTest.class AllocInfo.class Append.class AuthListFiles.class CallNamedPipe.class CopyTo.class CreateFile.class Delete.class Equals.class Exists.class FileInfo.class FileOps.class FilterFiles.class Format.class GetDate.class GetDfsPath.class Get.class GetType.class GetURL.class GrowWrite.class HttpURL.class Interleave.class IsDir.class Length.class ListFiles.class List.class ListTypes.class Mkdir.class NodeStatus.class OpenExclusive.class PeekNamedPipe.class PipeTalk.class Put.class Query.class RenameTo.class SetAttrs.class SetTime.class SlowRead.class SlowWrite.class SmbCrawler.class SmbShell.class SmbTableFile.class SmbTableFileRecord.class T2Crawler.class TestRandomAccess.class TestSmbURL.class TestUnicode.class ThreadedNbtQuery.class ThreadedSmbCrawler.class ThreadedUniQuery.class Torture1.class Torture2.class TortureTest5.class TransactNamedPipe.class URLTest.class VerifyGuest.class VerifyIO.class VerifyReads.class + +all: ${CLASSFILES} + +.java.class: + ${JAVA_HOME}/bin/javac -classpath ${CLASSPATH} $< + +clean: + ${RM} *.class diff --git a/examples/Mkdir.java b/examples/Mkdir.java new file mode 100644 index 0000000..a8b1cfc --- /dev/null +++ b/examples/Mkdir.java @@ -0,0 +1,9 @@ +import jcifs.smb.SmbFile; + +public class Mkdir { + + public static void main( String argv[] ) throws Exception { + (new SmbFile( argv[0] )).mkdir(); + } +} + diff --git a/examples/MultiLogon.java b/examples/MultiLogon.java new file mode 100644 index 0000000..6c56d95 --- /dev/null +++ b/examples/MultiLogon.java @@ -0,0 +1,21 @@ +import jcifs.smb.*; + +public class MultiLogon { + + public static void main( String argv[] ) throws Exception { + if (argv.length < 1) { + System.err.println( "usage: Dual \n"); + return; + } + + NtlmPasswordAuthentication auth1 = new NtlmPasswordAuthentication( argv[0] ); + NtlmPasswordAuthentication auth2 = new NtlmPasswordAuthentication( argv[1] ); + + SmbFile f1 = new SmbFile( argv[2], auth1 ); + SmbFile f2 = new SmbFile( argv[2], auth2 ); + + f1.exists(); + f2.exists(); + } +} + diff --git a/examples/NodeStatus.java b/examples/NodeStatus.java new file mode 100644 index 0000000..a0de5ba --- /dev/null +++ b/examples/NodeStatus.java @@ -0,0 +1,11 @@ +import jcifs.netbios.NbtAddress; + +public class NodeStatus { + + public static void main( String argv[] ) throws Exception { + NbtAddress[] addrs = NbtAddress.getAllByAddress( argv[0] ); + for( int i = 0; i < addrs.length; i++ ) { + System.out.println( addrs[i] ); + } + } +} diff --git a/examples/NtlmHttpAuthExample.java b/examples/NtlmHttpAuthExample.java new file mode 100644 index 0000000..d991a61 --- /dev/null +++ b/examples/NtlmHttpAuthExample.java @@ -0,0 +1,32 @@ +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; + +public class NtlmHttpAuthExample extends HttpServlet { + + public void doGet( HttpServletRequest req, + HttpServletResponse resp ) throws IOException, ServletException { + PrintWriter out = resp.getWriter(); + + resp.setContentType( "text/html" ); + out.println( "NTLM HTTP Authentication Example" ); + out.println( "

NTLM HTTP Authentication Example

" ); + + out.println( req.getRemoteUser() + " successfully logged in" ); + + out.println( "

Please submit some form data using POST

" ); + out.println( "
" ); + out.println( "" ); + out.println( "" ); + out.println( "
" ); + + out.println( "field1 = " + req.getParameter( "field1" )); + + out.println( "" ); + } + public void doPost( HttpServletRequest req, + HttpServletResponse resp ) throws IOException, ServletException { + doGet( req, resp ); + } +} + diff --git a/examples/NtlmHttpClient.java b/examples/NtlmHttpClient.java new file mode 100644 index 0000000..98d8914 --- /dev/null +++ b/examples/NtlmHttpClient.java @@ -0,0 +1,49 @@ +import java.io.*; + +import java.net.*; + +import jcifs.*; + +public class NtlmHttpClient { + + public static void main(String[] args) throws Exception { + // Normally set this outside application. + // Note that as a side effect due to the way handlers are located, + // you can also achieve this by simply doing: + Config.registerSmbURLHandler(); + // which we already do to register the smb handler. + //String pkgs = System.getProperty("java.protocol.handler.pkgs"); + //pkgs = (pkgs != null) ? "jcifs|" + pkgs : "jcifs"; + //System.setProperty("java.protocol.handler.pkgs", pkgs); + // + + if (args == null || args.length < 4) { + System.out.println("NtlmHttpClient "); + System.exit(1); + } + String location = args[0]; + String domain = args[1]; + String user = args[2]; + String password = args[3]; + // can also specify these in the URL, i.e. + // http://DOMAIN%5cuser:password@host/dir/file.html + // which will override these properties + Config.setProperty("jcifs.smb.client.domain", domain); + Config.setProperty("jcifs.smb.client.username", user); + Config.setProperty("jcifs.smb.client.password", password); + + try { + Config.setProperty("jcifs.netbios.hostname", + Config.getProperty("jcifs.netbios.hostname", + InetAddress.getLocalHost().getHostName())); + } catch (Exception ex) { } + URL url = new URL(location); + BufferedReader reader = new BufferedReader( + new InputStreamReader(url.openStream())); + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + } + +} diff --git a/examples/OpenExclusive.java b/examples/OpenExclusive.java new file mode 100644 index 0000000..8f80a78 --- /dev/null +++ b/examples/OpenExclusive.java @@ -0,0 +1,20 @@ +import jcifs.smb.SmbFile; +import jcifs.smb.SmbFileOutputStream; + +public class OpenExclusive { + + public static void main( String argv[] ) throws Exception { + SmbFileOutputStream out; + SmbFile f = new SmbFile( argv[0], "", null, SmbFile.FILE_NO_SHARE ); + out = new SmbFileOutputStream( f ); +System.in.read(); + out.close(); +System.in.read(); +// OR + out = new SmbFileOutputStream( argv[1], SmbFile.FILE_NO_SHARE ); +System.in.read(); + out.close(); +System.in.read(); + } +} + diff --git a/examples/PeekNamedPipe.java b/examples/PeekNamedPipe.java new file mode 100644 index 0000000..ab29540 --- /dev/null +++ b/examples/PeekNamedPipe.java @@ -0,0 +1,64 @@ +import jcifs.smb.SmbNamedPipe; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +public class PeekNamedPipe { + + static class ReceiverThread extends Thread { + InputStream in; + byte[] buf = new byte[20]; + int n; + + ReceiverThread( InputStream in ) { + this.in = in; + } + public void run() { + try { + while( true ) { + while(( n = in.available() ) == 0 ) { + System.out.println( "0 available" ); + sleep( 3000 ); + } + System.out.println( n + " available" ); + + if(( n = in.read( buf )) == -1 ) { + break; + } + System.out.println( new String( buf, 0, n )); + } + } catch( Exception e ) { + e.printStackTrace(); + } + System.out.println( "run finished" ); + } + } + + public static void main( String[] argv ) throws Exception { + SmbNamedPipe pipe = new SmbNamedPipe( argv[0], SmbNamedPipe.PIPE_TYPE_RDWR ); + InputStream in = pipe.getNamedPipeInputStream(); + OutputStream out = pipe.getNamedPipeOutputStream(); + + ReceiverThread rt = new ReceiverThread( in ); + rt.start(); + + StringBuffer sb = new StringBuffer(); + String msg; + int c; + while(( c = System.in.read() ) != -1 ) { + if( c == '\n' ) { + msg = sb.toString(); + if( msg.startsWith( "exi" )) { + break; + } + out.write( msg.getBytes() ); + sb.setLength( 0 ); + } else { + sb.append( (char)c ); + } + } + in.close(); + out.close(); + } +} + diff --git a/examples/PipeTalk.java b/examples/PipeTalk.java new file mode 100644 index 0000000..1ca635f --- /dev/null +++ b/examples/PipeTalk.java @@ -0,0 +1,56 @@ +import jcifs.smb.SmbNamedPipe; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +public class PipeTalk { + + static class ReceiverThread extends Thread { + InputStream in; + byte[] buf = new byte[20]; + int n; + + ReceiverThread( InputStream in ) { + this.in = in; + } + public void run() { + try { + while(( n = in.read( buf )) != -1 ) { + System.out.println( new String( buf, 0, n )); + } + } catch( IOException ioe ) { + ioe.printStackTrace(); + } + } + } + + public static void main( String argv[] ) throws Exception { + + SmbNamedPipe pipe = new SmbNamedPipe( argv[0], SmbNamedPipe.PIPE_TYPE_RDWR ); + InputStream in = pipe.getNamedPipeInputStream(); + OutputStream out = pipe.getNamedPipeOutputStream(); + + ReceiverThread rt = new ReceiverThread( in ); + rt.start(); + + StringBuffer sb = new StringBuffer(); + String msg; + int c; + while(( c = System.in.read() ) != -1 ) { + if( c == '\n' ) { + msg = sb.toString(); + if( msg.startsWith( "exi" )) { + break; + } + System.out.println( sb.toString() ); + out.write( msg.getBytes() ); + sb.setLength( 0 ); + } else { + sb.append( (char)c ); + } + } + in.close(); + out.close(); + } +} + diff --git a/examples/Put.java b/examples/Put.java new file mode 100644 index 0000000..d5c6438 --- /dev/null +++ b/examples/Put.java @@ -0,0 +1,31 @@ +import jcifs.smb.SmbFile; +import jcifs.smb.SmbFileOutputStream; +import java.io.FileInputStream; + +public class Put { + + public static void main( String argv[] ) throws Exception { + + SmbFile f = new SmbFile( argv[0] ); + FileInputStream in = new FileInputStream( f.getName() ); + SmbFileOutputStream out = new SmbFileOutputStream( f ); + + long t0 = System.currentTimeMillis(); + + byte[] b = new byte[8192]; + int n, tot = 0; + while(( n = in.read( b )) > 0 ) { + out.write( b, 0, n ); + tot += n; + System.out.print( '#' ); + } + + long t = System.currentTimeMillis() - t0; + + System.out.println(); + System.out.println( tot + " bytes transfered in " + ( t / 1000 ) + " seconds at " + (( tot / 1000 ) / Math.max( 1, ( t / 1000 ))) + "Kbytes/sec" ); + + in.close(); + out.close(); + } +} diff --git a/examples/Query.java b/examples/Query.java new file mode 100644 index 0000000..400c7fa --- /dev/null +++ b/examples/Query.java @@ -0,0 +1,18 @@ +import jcifs.netbios.NbtAddress; +import jcifs.UniAddress; +import java.net.InetAddress; + +public class Query { + + public static void main( String argv[] ) throws Exception { + UniAddress ua; + String cn; + + ua = UniAddress.getByName( argv[0] ); + + cn = ua.firstCalledName(); + do { + System.out.println( "calledName=" + cn ); + } while(( cn = ua.nextCalledName() ) != null ); + } +} diff --git a/examples/RenameTo.java b/examples/RenameTo.java new file mode 100644 index 0000000..c9f6787 --- /dev/null +++ b/examples/RenameTo.java @@ -0,0 +1,12 @@ +import jcifs.smb.SmbFile; + +public class RenameTo { + + public static void main( String argv[] ) throws Exception { + + SmbFile from = new SmbFile( argv[0] ); + SmbFile to = new SmbFile( argv[1] ); + from.renameTo( to ); + } +} + diff --git a/examples/SetAttrs.java b/examples/SetAttrs.java new file mode 100644 index 0000000..ceaad2f --- /dev/null +++ b/examples/SetAttrs.java @@ -0,0 +1,18 @@ +import jcifs.smb.*; + +public class SetAttrs { + + public static void main( String argv[] ) throws Exception { + if( argv.length < 2 ) { + System.err.println( "usage: SetAttrs " ); + return; + } + + SmbFile f = new SmbFile( argv[0] ); + SmbFileInputStream in = new SmbFileInputStream( f ); + int attrs = Integer.parseInt( argv[1], 16 ); + + f.setAttributes( attrs ); + } +} + diff --git a/examples/SetTime.java b/examples/SetTime.java new file mode 100644 index 0000000..fbfd3c8 --- /dev/null +++ b/examples/SetTime.java @@ -0,0 +1,12 @@ +import jcifs.smb.SmbFile; +import jcifs.smb.SmbException; + +public class SetTime { + + public static void main( String argv[] ) throws Exception { + SmbFile f = new SmbFile( argv[0] ); + long time = f.getLastModified(); + f.setLastModified( time + 65000 ); /* add 1 minute and 5 seconds */ + } +} + diff --git a/examples/SidCacheTest.java b/examples/SidCacheTest.java new file mode 100644 index 0000000..ac47af8 --- /dev/null +++ b/examples/SidCacheTest.java @@ -0,0 +1,20 @@ +import jcifs.smb.*; + +public class SidCacheTest { + + public static void main( String[] argv ) throws Exception { + long t1, t2, t3; + SmbFile file; + ACE[] security; + int ai; + + file = new SmbFile(argv[0]); + t1 = System.currentTimeMillis(); + security = file.getSecurity(true); + t2 = System.currentTimeMillis(); + security = file.getSecurity(true); + t3 = System.currentTimeMillis(); + + System.out.println("dt1=" + (t2 - t1) + ",dt2=" + (t3 - t2) + " " + ((t2 - t1) / (t3 - t2)) + "x increase"); + } +} diff --git a/examples/SidCrawler.java b/examples/SidCrawler.java new file mode 100644 index 0000000..2ef8035 --- /dev/null +++ b/examples/SidCrawler.java @@ -0,0 +1,61 @@ +import java.util.LinkedList; +import java.util.ListIterator; +import java.net.MalformedURLException; +import java.io.IOException; + +import jcifs.smb.*; + +public class SidCrawler { + + static final byte[] SP = " ".getBytes(); + + static void printSpace(int count) { + if (count > SP.length) + count = SP.length; + System.out.write(SP, 0, count); + } + + int maxDepth; + + SidCrawler( int maxDepth ) { + this.maxDepth = maxDepth; + } + + void traverse( SmbFile f, int depth ) throws MalformedURLException, IOException { + int indent = maxDepth - depth; + + if( depth == 0 ) { + return; + } + + SmbFile[] l = f.listFiles(); + + for(int i = 0; l != null && i < l.length; i++ ) { + try { + printSpace(indent * 4); + ACE[] acl = l[i].getSecurity(true); + System.out.println( l[i] ); + for (int ai = 0; ai < acl.length; ai++) { + printSpace((indent + 1) * 4); + System.out.println("+ " + acl[ai].toString()); + } + if( l[i].isDirectory() ) { + traverse( l[i], depth - 1 ); + } + } catch( IOException ioe ) { + System.out.println( l[i] + ":" ); + ioe.printStackTrace( System.out ); + } + } + } + + public static void main(String[] argv) throws Exception { + if (argv.length < 2) { + System.err.println("usage: SidCrawler "); + return; + } + int depth = Integer.parseInt( argv[1] ); + SidCrawler sc = new SidCrawler( depth ); + sc.traverse( new SmbFile( argv[0] ), depth ); + } +} diff --git a/examples/SidFragment.java b/examples/SidFragment.java new file mode 100644 index 0000000..214778c --- /dev/null +++ b/examples/SidFragment.java @@ -0,0 +1,28 @@ +import jcifs.smb.*; + +public class SidFragment { + + public static void main(String[] argv) throws Exception { + if (argv.length < 1) { + System.err.println("usage: SidFragment "); + return; + } + + SID domsid = new SID(argv[0]); + int rid = 1120; + int count = 150; + int si; + + SID[] sids = new SID[count]; + + for (si = 0; si < sids.length; si++) { + sids[si] = new SID(domsid, rid++); + } + + SID.resolveSids("ts0", null, sids); + + for (si = 0; si < sids.length; si++) { + System.out.println(sids[si].toString()); + } + } +} diff --git a/examples/SidLookup.java b/examples/SidLookup.java new file mode 100644 index 0000000..0623499 --- /dev/null +++ b/examples/SidLookup.java @@ -0,0 +1,20 @@ +import jcifs.smb.*; + +public class SidLookup { + + public static void main(String[] argv) throws Exception { + if (argv.length < 1) { + System.err.println("usage: SidLookup S-1-5-21-1496946806-2192648263-3843101252"); + return; + } + + SID sid = new SID(argv[0]); + sid.resolve("ts0", null); + System.out.println(" toString: " + sid.toString()); + System.out.println(" toSidString: " + sid.toDisplayString()); + System.out.println(" getType: " + sid.getType()); + System.out.println(" getTypeText: " + sid.getTypeText()); + System.out.println(" getDomainName: " + sid.getDomainName()); + System.out.println("getAccountName: " + sid.getAccountName()); + } +} diff --git a/examples/SlowRead.java b/examples/SlowRead.java new file mode 100644 index 0000000..3fa42ad --- /dev/null +++ b/examples/SlowRead.java @@ -0,0 +1,22 @@ +import jcifs.smb.SmbFile; +import jcifs.smb.SmbFileInputStream; +import java.io.FileOutputStream; + +public class SlowRead { + + public static void main( String argv[] ) throws Exception { + + SmbFileInputStream in = new SmbFileInputStream( argv[0] ); + + byte[] b = new byte[10]; + int n, tot = 0; + while(( n = in.read( b )) > 0 ) { + System.out.write( b, 0, n ); + tot += n; + Thread.sleep( 10000 ); + } + + in.close(); + } +} + diff --git a/examples/SlowWrite.java b/examples/SlowWrite.java new file mode 100644 index 0000000..4ecd365 --- /dev/null +++ b/examples/SlowWrite.java @@ -0,0 +1,17 @@ +import jcifs.smb.SmbFileOutputStream; + +public class SlowWrite { + + public static void main( String argv[] ) throws Exception { + + SmbFileOutputStream out = new SmbFileOutputStream( argv[0] ); + + for( int i = 0; i < 2; i++ ) { + out.write( (new String( "hello" + i )).getBytes() ); + Thread.sleep( 17000 ); + } + + out.close(); + } +} + diff --git a/examples/SmbCrawler.java b/examples/SmbCrawler.java new file mode 100644 index 0000000..72a8e10 --- /dev/null +++ b/examples/SmbCrawler.java @@ -0,0 +1,44 @@ +import jcifs.smb.SmbFile; +import java.util.LinkedList; +import java.util.ListIterator; +import java.net.MalformedURLException; +import java.io.IOException; + +public class SmbCrawler { + + int maxDepth; + + SmbCrawler( int maxDepth ) { + this.maxDepth = maxDepth; + } + + void traverse( SmbFile f, int depth ) throws MalformedURLException, IOException { + + if( depth == 0 ) { + return; + } + + SmbFile[] l = f.listFiles(); + + for(int i = 0; l != null && i < l.length; i++ ) { + try { + for( int j = maxDepth - depth; j > 0; j-- ) { + System.out.print( " " ); + } + System.out.println( l[i] + " " + l[i].exists() ); + if( l[i].isDirectory() ) { + traverse( l[i], depth - 1 ); + } + } catch( IOException ioe ) { + System.out.println( l[i] + ":" ); + ioe.printStackTrace( System.out ); + } + } + } + + public static void main(String[] argv) throws Exception { + int depth = Integer.parseInt( argv[1] ); + SmbCrawler sc = new SmbCrawler( depth ); + sc.traverse( new SmbFile( argv[0] ), depth ); + } +} diff --git a/examples/SmbShell.java b/examples/SmbShell.java new file mode 100644 index 0000000..d7fdcf2 --- /dev/null +++ b/examples/SmbShell.java @@ -0,0 +1,190 @@ +/* examples for the jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * 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. + */ + +import jcifs.smb.*; +import java.net.UnknownHostException; +import java.net.MalformedURLException; +import java.util.GregorianCalendar; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class SmbShell extends NtlmAuthenticator { + + protected NtlmPasswordAuthentication getNtlmPasswordAuthentication() { + System.out.println( getRequestingException().getMessage() + + " for " + getRequestingURL() ); + System.out.print( "username: " ); + try { + int i; + String username = readLine(); + String domain = null, password; + + if(( i = username.indexOf( '\\' )) != -1 ) { + domain = username.substring( 0, i ); + username = username.substring( i + 1 ); + } + System.out.print( "password: " ); + password = readLine(); + if( password.length() == 0 ) { + return null; + } + return new NtlmPasswordAuthentication( domain, username, password ); + } catch( Exception e ) { + } + return null; + } + + public static String readLine() throws Exception { + int c; + StringBuffer sb = new StringBuffer(); + while(( c = System.in.read() ) != '\n' ) { + if( c == -1 ) return ""; + sb.append( (char)c ); + } + return sb.toString().trim(); + } + + String start; + + public SmbShell( String start ) { + this.start = start; + NtlmAuthenticator.setDefault( this ); + } + + void run() throws Exception { + int c; + String cmd, prompt; + SmbFile conn, tmp; + SimpleDateFormat sdf1 = new SimpleDateFormat( "EEE MMM" ); + SimpleDateFormat sdf2 = new SimpleDateFormat( "d" ); + SimpleDateFormat sdf3 = new SimpleDateFormat( "yyyy h:mm a" ); + sdf1.setCalendar( new GregorianCalendar() ); + sdf2.setCalendar( new GregorianCalendar() ); + sdf3.setCalendar( new GregorianCalendar() ); + + conn = new SmbFile( start ); + while( true ) { + try { + if( conn.exists() ) { + prompt = conn.getName() + "> "; + } else { + System.out.println( "error reading " + conn ); + conn = new SmbFile( "smb://" ); + continue; + } + System.out.print( prompt ); + + cmd = readLine(); + if( cmd.equals( "" ) ) { + } else if( cmd.startsWith( "cd" )) { + int i = cmd.indexOf( ' ' ); + String dir; + if( i == -1 || (dir = cmd.substring( i ).trim()).length() == 0 ) { + conn = new SmbFile( "smb://" ); + continue; + } + tmp = new SmbFile( conn, dir ); + if( tmp.exists() ) { + if( tmp.isDirectory() ) { + conn = tmp; + } else { + System.out.println( dir + " is not a directory" ); + } + } else { + System.out.println( "no such directory" ); + } + } else if( cmd.startsWith( "ls" )) { + int i = cmd.indexOf( ' ' ); + SmbFile d = conn; + String dir, wildcard = "*"; + if( i != -1 && (dir = cmd.substring( i ).trim()).length() != 0 ) { + // there's an argument which could be a directory, + // a wildcard, or a directory with a wildcard appended + int s = dir.lastIndexOf( '/' ); + int a = dir.lastIndexOf( '*' ); + int q = dir.lastIndexOf( '?' ); + + if(( a != -1 && a > s ) || ( q != -1 && q > s )) { + // it's a wildcard + if( s == -1 ) { + wildcard = dir; + d = conn; + } else { + wildcard = dir.substring( s + 1 ); + d = new SmbFile( conn, dir.substring( 0, s )); + } + } else { + d = new SmbFile( conn, dir ); + } + } + long t0 = System.currentTimeMillis(); + SmbFile[] list = d.listFiles( wildcard ); + t0 = System.currentTimeMillis() - t0; + if( list != null ) { + for( int j = 0; j < list.length; j++ ) { + StringBuffer sb = new StringBuffer(); + Date date = new Date( list[j].lastModified() ); + Format.print( System.out, "%-40s", list[j].getName() ); + sb.append( list[j].isDirectory() ? 'd' : '-' ); + sb.append( list[j].canRead() ? 'r' : '-' ); + sb.append( list[j].canWrite() ? 'w' : '-' ); + sb.append( list[j].isHidden() ? 'h' : '-' ); + sb.append( list[j].getType() == SmbFile.TYPE_WORKGROUP ? 'g' : '-' ); + Format.print( System.out, "%-6s", sb.toString() ); + Format.print( System.out, "%10d ", list[j].length() ); + + System.out.print( sdf1.format( date )); + Format.print( System.out, "%3s ", sdf2.format( date )); + System.out.print( sdf3.format( date )); + System.out.println(); + } + System.out.println( list.length + " items in " + t0 + "ms" ); + } else { + System.out.println( "no such file or directory" ); + } + } else if( cmd.startsWith( "pwd" )) { + System.out.println( conn.getCanonicalPath() ); + } else if( cmd.startsWith( "q" ) || + cmd.startsWith( "x" ) || + cmd.startsWith( "ex" ) || + cmd.startsWith( "by" )) { + break; + } else { + System.out.println( "commands:" ); + System.out.println( " ls [dir|file]" ); + System.out.println( " cd dir" ); + System.out.println( " pwd" ); + System.out.println( " quit" ); + } + } catch( MalformedURLException mue ) { + mue.printStackTrace(); + conn = null; + } catch( SmbException se ) { + se.printStackTrace(); + } catch( Exception e ) { + e.printStackTrace(); + System.exit( 1 ); + } + } + System.exit( 0 ); + } + public static void main( String[] argv ) throws Exception { + SmbShell smbsh = new SmbShell( argv.length > 0 ? argv[0] : "smb://" ); + smbsh.run(); + } +} diff --git a/examples/SmbTableFile.java b/examples/SmbTableFile.java new file mode 100644 index 0000000..4d3837f --- /dev/null +++ b/examples/SmbTableFile.java @@ -0,0 +1,128 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +import jcifs.smb.*; +import java.io.*; + +public class SmbTableFile extends SmbRandomAccessFile { + + static final byte BYTE_FULL = (byte)0xFF; + + byte[] hdr = new byte[512]; + byte[] buf = new byte[1024]; + char[] cbuf = new char[512]; + int recordSize, row; + + public SmbTableFile( SmbFile file, String mode, int recordSize ) throws IOException { + super( file, mode ); + this.recordSize = recordSize; + read( hdr, 0, 512 ); + } + public SmbTableFile( String url, String mode, int shareAccess, int recordSize ) throws IOException { + super( url, mode, shareAccess ); + this.recordSize = recordSize; + read( hdr, 0, 512 ); + } + + public void insert( SmbTableFileRecord tfr ) throws IOException { + int i, b = 0; + + /* Find an unset bit it in the bitmap + */ + for( i = 128; i < 512; i++ ) { + if( hdr[i] != BYTE_FULL ) { + /* bitwise complement inverts each bit + * mask with 0xFF ensures we only use 8 bits of int b + */ + b = ~hdr[i] & 0xFF; + /* clever trick to isolate first bit on + */ + b = b & -b; + break; + } + } + if( i == 512 ) { + throw new IOException( "No more space in " + this ); + } + /* convert power of two to position + */ + switch( b ) { + case 1: b = 0; break; + case 2: b = 1; break; + case 4: b = 2; break; + case 8: b = 3; break; + case 16: b = 4; break; + case 32: b = 5; break; + case 64: b = 6; break; + case 128: b = 7; break; + } + tfr.rowid = (i - 128) * 8 + b; + update( tfr ); + } + public void update( SmbTableFileRecord tfr ) throws IOException { + int i; + + seek( 512L + tfr.rowid * recordSize ); + tfr.encode( this ); + + i = 128 + tfr.rowid / 8; + seek( i ); + hdr[i] |= 1 << (tfr.rowid % 8); + write( hdr[i] ); + } + public void get( SmbTableFileRecord tfr ) throws IOException { + seek( 512L + tfr.rowid * recordSize ); + tfr.decode( this ); + } + public void iterate() { + row = 0; + } + public boolean next( SmbTableFileRecord tfr ) throws IOException { + int i, b; + + i = 128 + row / 8; /* Search bitmap for next bit that is on */ + b = 1 << (row % 8); + for( ; i < 512; i++ ) { + if(( hdr[i] & -b ) != 0 ) { + b = hdr[i] & -b; + b = b & -b; + break; + } + b = 1; + } + if( i == 512 ) { /* Are no more on bits, return */ + return false; + } + switch( b ) { + case 1: b = 0; break; + case 2: b = 1; break; + case 4: b = 2; break; + case 8: b = 3; break; + case 16: b = 4; break; + case 32: b = 5; break; + case 64: b = 6; break; + case 128: b = 7; break; + } + tfr.rowid = (i - 128) * 8 + b; /* Set rowid and get */ + get( tfr ); + + row = tfr.rowid + 1; /* Iterate row for next caller */ + + return true; + } +} diff --git a/examples/SmbTableFileRecord.java b/examples/SmbTableFileRecord.java new file mode 100644 index 0000000..f842892 --- /dev/null +++ b/examples/SmbTableFileRecord.java @@ -0,0 +1,25 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +import jcifs.smb.SmbException; + +public abstract class SmbTableFileRecord { + public int rowid; + public abstract void encode( SmbTableFile tf ) throws SmbException; + public abstract void decode( SmbTableFile tf ) throws SmbException; +} diff --git a/examples/SmbThreadTest.java b/examples/SmbThreadTest.java new file mode 100644 index 0000000..93b68b4 --- /dev/null +++ b/examples/SmbThreadTest.java @@ -0,0 +1,134 @@ +import jcifs.smb.SmbFile; +import jcifs.smb.NtlmPasswordAuthentication; +import jcifs.smb.SmbAuthException; + + +import java.util.Random; +import java.net.MalformedURLException; +import java.io.IOException; + +public class SmbThreadTest extends Thread { + + int maxDepth; + int id; + String url; + NtlmPasswordAuthentication auth; + long start_time; + + static Random rnd = new Random(1234); + static long test_time = 100*1000; + static long num_sessions = 1000; + static long session_time = (test_time / num_sessions) * 400; + + static boolean verbose = false; + + + SmbThreadTest(NtlmPasswordAuthentication auth, String url, int maxDepth, int id) { + this.url = url; + this.auth = auth; + this.maxDepth = maxDepth; + this.id = id; + this.start_time = System.currentTimeMillis(); + } + + void traverse( SmbFile f, int depth ) throws MalformedURLException, IOException { + + if( depth == 0 ) { + return; + } + SmbFile[] l = null; + try { + if (f.exists()) + l = f.listFiles(); + } catch (SmbAuthException ae) { + System.err.println("SAE: " + ae.getMessage()); + ae.printStackTrace( System.err ); + return; + } catch (NullPointerException npe) { + System.err.println("NPE"); + npe.printStackTrace( System.err ); + return; + } + for(int i = 0; l != null && i < l.length; i++ ) { + try { + boolean exists = l[i].exists(); + if (verbose) { + System.out.print(id); + for( int j = maxDepth - depth; j > 0; j-- ) { + System.out.print( " " ); + } + System.out.println( l[i] + " " + exists ); + } + if( l[i].isDirectory() ) { + traverse( l[i], depth - 1 ); + } + } catch (SmbAuthException ae) { + System.err.println("SAE: " + ae.getMessage()); + ae.printStackTrace( System.err ); + } catch( IOException ioe ) { + System.out.println( l[i] + ":" ); + ioe.printStackTrace( System.out ); + } + try { + Thread.sleep(Math.abs(rnd.nextInt(2)+1)); + } catch (InterruptedException e) { + + } + } + } + + public void run () { + SmbFile f = null; + int runs = 0; + while(true) { + try { + Thread.sleep(100); + }catch (InterruptedException e) {} + + while (f == null) { + try { + f = new SmbFile(url, auth); + } catch (Exception e) { + System.err.println(e.getMessage()); + e.printStackTrace(); + } + } + try { + traverse(f, maxDepth); + } catch (Exception e) { + System.err.println(e.getMessage()); + e.printStackTrace(); + } + runs++; + long time = System.currentTimeMillis() - start_time; + if (time > session_time) { + System.err.println(id + " exit (" + time/runs + ")"); + return; + } + } + } + + public static void createThreads(String url, int i, int count) { + NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(null); + int num = 0; + System.err.println("creating " + count + " threads"); + while (num < count) { + SmbThreadTest sc = new SmbThreadTest(auth, url, 3, i * 100 + num++); + sc.start(); + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + + public static void main(String[] argv) throws Exception { + for(int i = 0; i < num_sessions; i++) { + createThreads(argv[0], i+1, Math.abs(rnd.nextInt(4)+1)); + sleep((test_time / num_sessions)*100); + } + sleep(6000000); + } +} + diff --git a/examples/SmbTimeout.java b/examples/SmbTimeout.java new file mode 100644 index 0000000..0733a33 --- /dev/null +++ b/examples/SmbTimeout.java @@ -0,0 +1,25 @@ +import jcifs.smb.SmbFile; + +public class SmbTimeout { + + public static void jcifsScan(String root, int sleepTime) throws Exception { + long start = System.currentTimeMillis(); + SmbFile smbRoot = new SmbFile(root); + SmbFile[] files = smbRoot.listFiles(); + for(SmbFile f : files) { + System.out.println( f + ": " + f.canRead()+" : "+ f.length() + ": " + (System.currentTimeMillis()-start)); + Thread.sleep(sleepTime); + } + } + + public static void main(String[] p_args) throws Exception { + if(p_args.length!=2) { + System.out.println("Usage: "); + return; + } + String smbRoot = p_args[0]; + int sleepTime = Integer.parseInt(p_args[1]); + jcifsScan(smbRoot,sleepTime); + } + +} diff --git a/examples/SsnLimit.java b/examples/SsnLimit.java new file mode 100644 index 0000000..528bc6e --- /dev/null +++ b/examples/SsnLimit.java @@ -0,0 +1,17 @@ +import jcifs.*; +import jcifs.smb.*; + +public class SsnLimit { + + public static void main( String argv[] ) throws Exception { + jcifs.Config.setProperty( "jcifs.smb.client.ssnLimit", "1" ); + NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication( null, null, null ); + UniAddress addr = UniAddress.getByName( argv[0] ); + for( int i = 0; i < 25; i++ ) { + SmbSession.logon( addr, auth ); + Thread.sleep( 1000 ); + } + Thread.sleep( 10000 ); + } +} + diff --git a/examples/T2Crawler.java b/examples/T2Crawler.java new file mode 100644 index 0000000..8a1aafa --- /dev/null +++ b/examples/T2Crawler.java @@ -0,0 +1,140 @@ +/* examples for the jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * 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. + */ + +import jcifs.smb.SmbFile; +import jcifs.util.*; +import java.util.LinkedList; +import java.util.ListIterator; +import java.net.MalformedURLException; +import java.io.IOException; + +public class T2Crawler { + + class Semaphore { + private int value = 0; + + Semaphore() {value = 0;} + Semaphore(int initial) {value = initial;} + + public synchronized void P() { + value--; + if (value < 0) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public synchronized void V() { + value++; + notify(); + } + } + + class CrawlerThread extends Thread { + LinkedList list; + Semaphore sem; + SmbFile dir; + int depth; + + + CrawlerThread( SmbFile dir, Semaphore sem, int depth ) { + this.dir = dir; + list = new LinkedList(); + list.add( dir ); + this.sem = sem; + this.depth = depth; + } + + public void run() { + SmbFile d; + SmbFile l[]; + + while( list.isEmpty() == false ) { + int i; + d = (SmbFile)list.remove( 0 ); + try { + l = d.listFiles(); + +/* This is flawed. It decrements depth too agressively and causes the + * thread to finish prematurely. I do not know of a way to fix this + * because there is no concept of a stack here. + */ + depth--; + for( i = 0; i < l.length; i++ ) { + System.out.println( l[i] ); + // if( depth++ > 0 && l[i].isDirectory() && !l[i].isHidden() ) { + if( depth > 0 && l[i].isDirectory() ) { + list.add( l[i] ); + } + } + } catch( Exception e ) { + System.out.println( d ); + e.printStackTrace(); + } + } + sem.V(); + } + } + + T2Crawler( String dir, int numThreads, int depth ) throws Exception { + SmbFile top = new SmbFile( dir ); + Semaphore sem = new Semaphore( numThreads ); + SmbFile[] l = null; + int i = 0; + + try { + l = top.listFiles(); + depth--; + for( i = 0; i < l.length; i++ ) { + try { + System.out.println( l[i] ); + if( !l[i].isDirectory() || l[i].isHidden() ) { + continue; + } + if( depth > 0 ) { + sem.P(); + (new CrawlerThread( l[i], sem, depth )).start(); + } + } catch( Exception e ) { + e.printStackTrace(); + } + } + for( i = 0; i < l.length; i++ ) { + try { + l[i].canRead(); + } catch(Exception ex) { + System.err.println( l[i] ); + ex.printStackTrace(); + } + } + } catch( Exception ex ) { + System.err.println( l[i] ); + ex.printStackTrace(); + } + } + public static void main(String[] argv) throws Exception { + if( argv.length < 3) { + System.out.println( "$ java -Djcifs.properties=miallen.prp T2Crawler "); + System.exit(1); + } + new T2Crawler( argv[0], Integer.parseInt( argv[1] ), Integer.parseInt( argv[2] )); + } +} diff --git a/examples/TestCopy.java b/examples/TestCopy.java new file mode 100644 index 0000000..6170a57 --- /dev/null +++ b/examples/TestCopy.java @@ -0,0 +1,25 @@ +import jcifs.smb.*; + +public class TestCopy { + + public static void main( String[] args ) throws Exception { + + if( args.length < 1 ) { + System.err.println( "usage: TestCopy [ [ " + args[i + 1] ); + e.printStackTrace(); + } + } + } +} diff --git a/examples/TestRandomAccess.java b/examples/TestRandomAccess.java new file mode 100644 index 0000000..312dacc --- /dev/null +++ b/examples/TestRandomAccess.java @@ -0,0 +1,121 @@ +import jcifs.smb.*; + +public class TestRandomAccess { + + public static class TestRecord extends SmbTableFileRecord { + + boolean f1; /* 1 byte */ + byte f2; /* 1 byte */ + int f3; /* 1 byte */ + short f4; /* 2 bytes */ + int f5; /* 2 bytes */ + char f6; /* 2 bytes */ + int f7; /* 4 bytes */ + long f8; /* 8 bytes */ + float f9; /* 4 bytes */ + double f10; /* 8 bytes */ + String f11; /* 95 bytes max */ + /* 128 bytes total */ + + public TestRecord() { + } + public TestRecord( boolean f1, byte f2, int f3, short f4, + int f5, char f6, int f7, long f8, + float f9, double f10, String f11 ) { + this.f1 = f1; + this.f2 = f2; + this.f3 = f3; + this.f4 = f4; + this.f5 = f5; + this.f6 = f6; + this.f7 = f7; + this.f8 = f8; + this.f9 = f9; + this.f10 = f10; + this.f11 = f11; + } + + public void encode( SmbTableFile tf ) throws SmbException { + tf.writeBoolean( f1 ); + tf.writeByte( f2 ); + tf.writeByte( f3 ); + tf.writeShort( f4 ); + tf.writeShort( f5 ); + tf.writeChar( f6 ); + tf.writeInt( f7 ); + tf.writeLong( f8 ); + tf.writeFloat( f9 ); + tf.writeDouble( f10 ); + tf.writeUTF( f11 ); + } + public void decode( SmbTableFile tf ) throws SmbException { + f1 = tf.readBoolean(); + f2 = tf.readByte(); + f3 = tf.readUnsignedByte(); + f4 = tf.readShort(); + f5 = tf.readUnsignedShort(); + f6 = tf.readChar(); + f7 = tf.readInt(); + f8 = tf.readLong(); + f9 = tf.readFloat(); + f10 = tf.readDouble(); + f11 = tf.readUTF(); + } + public boolean equals( Object obj ) { + if( obj instanceof TestRecord ) { + TestRecord r = (TestRecord)obj; + + return r.f1 == f1 && + r.f2 == f2 && + r.f3 == f3 && + r.f4 == f4 && + r.f5 == f5 && + r.f6 == f6 && + r.f7 == f7 && + r.f8 == f8 && + r.f9 == f9 && + r.f10 == f10 && + f11.equals( r.f11 ); + } + return false; + } + } + + public static void main( String[] argv ) throws Exception { + if( argv.length < 2 ) { + System.err.println( "usage: TestRandomAccess (1 for read or 2 for write with )" ); + return; + } + SmbTableFile stf; + int op = Integer.parseInt( argv[1] ); + + TestRecord r1 = new TestRecord( true, (byte)0x12, 0x34, (short)0x1122, + 0x3344, '\u04c1', 0x11112222, 0x1111111122222222L, + 0.1122f, 3344.1, "The surface is smooth like glass" ); + + if( op == 3 ) { + stf = new SmbTableFile( argv[0], "rw", 0, 128 ); + int newLength = Integer.parseInt( argv[2] ); + stf.setLength( newLength ); + System.out.println( "truncated to " + newLength ); + } else if( op == 1 ) { + SmbFile file = new SmbFile( argv[0], null, SmbFile.FILE_SHARE_READ ); + stf = new SmbTableFile( file, "rw", 128 ); + stf.insert( r1 ); + System.out.println( "rowid: " + r1.rowid ); + } else { + if( argv.length < 3 ) { + System.err.println( "usage: TestRandomAccess (1 for read or 2 for write with )" ); + return; + } + stf = new SmbTableFile( argv[0], "r", 0, 128 ); + TestRecord r2 = new TestRecord(); + r2.rowid = Integer.parseInt( argv[2] ); + stf.get( r2 ); + System.out.println( "r1.equals( r2 ) = " + r1.equals( r2 )); + } + + stf.close(); + } +} + diff --git a/examples/TestSmbURL.java b/examples/TestSmbURL.java new file mode 100644 index 0000000..3606d82 --- /dev/null +++ b/examples/TestSmbURL.java @@ -0,0 +1,164 @@ +import java.util.Date; +import jcifs.smb.*; +import java.io.*; + +public class TestSmbURL { + + static void test( String url, String name ) throws Exception { + SmbFile f; + + if( name == null ) name = ""; + + System.out.println( "INPUT[" + url + ", " + name + "]"); + try { + f = new SmbFile( url, name ); + } catch( Exception e ) { + e.printStackTrace(); + return; + } + + System.out.print( "toString() : " ); + try { + System.out.println( f.toString() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "getCanonicalPath() : " ); + try { + System.out.println( f.getCanonicalPath() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "getUncPath() : " ); + try { + System.out.println( f.getUncPath() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "getName() : " ); + try { + System.out.println( f.getName() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "getParent() : " ); + try { + System.out.println( f.getParent() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "getPath() : " ); + try { + System.out.println( f.getPath() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "getServer() : " ); + try { + System.out.println( f.getServer() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "getShare() : " ); + try { + System.out.println( f.getShare() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "exists() : " ); + try { + System.out.println( f.exists() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "isDirectory() : " ); + try { + System.out.println( f.isDirectory() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "isFile() : " ); + try { + System.out.println( f.isFile() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "length() : " ); + try { + System.out.println( f.length() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "lastModified() : " ); + try { + System.out.println( (new Date( f.lastModified() ))); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + System.out.print( "toURL().toString() : " ); + try { + System.out.println( f.toURL() ); + } catch( Exception e ) { + e.printStackTrace(); System.out.println(); + } + + System.in.read(); + } + + public static void main( String argv[] ) throws Exception { + String workgroup, server, share, path, file; + + if( argv.length < 5 ) { + System.err.println( "TestSmbURL workgroup server share path file" ); + System.exit( 1 ); + } + + workgroup = argv[0]; + server = argv[1]; + share = argv[2]; + path = argv[3]; + file = argv[4]; + +/* + System.out.println(); + System.out.println( "-- UNUSUAL --" ); + System.out.println(); + test( "smb://" + server, "../" + server + "/" + share ); + test( "smb://foo", "../" + workgroup ); + test( "smb://", ".." ); +*/ + + System.out.println(); + System.out.println( "-- BASICS: ONE ARGUMENT --" ); + System.out.println(); + test( "smb://" + server + "/" + share + "/" + path + "/" + file, null ); + test( "smb://" + server + "/" + share + "/" + path + "/", null ); + test( "smb://" + server + "/" + share + "/", null ); + test( "smb://" + server + "/", null ); + test( "smb://" + workgroup + "/", null ); + test( "smb://", null ); + + System.out.println(); + System.out.println( "-- BASICS: TWO ARGUMENTS --" ); + System.out.println(); + test( "smb://" + server + "/" + share + "/" + path + "/", file); + test( "smb://" + server + "/" + share + "/", path + "/" + file); + test( "smb://" + server + "/", share + "/" + path + "/" + file); + test( "smb://", server + "/" + share + "/" + path + "/" + file); + test( "smb://", "smb://" + server + "/" + share + "/" + path + "/" + file); + test( "smb://", "smb://" + server + "/"); + test( "smb://", "smb://" + workgroup + "/"); + test( "smb://", "smb://"); + test( "smb://" + server + "/share/", "smb://"); + + System.out.println(); + System.out.println( "-- CANONICALIZATION --" ); + System.out.println(); + test( "smb://" + server + "/" + share + "/foo/../" + path + "/" + file, null ); + test( "smb://" + server + "/foo/bar/.././../" + share + "/" + path + "/" + file, null ); + test( "smb://" + server + "/foo/bar/.././.././" + share + "/fake/../" + path + "/" + file, null ); + test( "smb://" + server + "/foo/bar/.././.././", share + "/fake/../" + path + "/" + file); + test( "smb://", server + "/foo/bar/.././.././" + share + "/fake/../" + path + "/" + file); + } +} + diff --git a/examples/TestUnicode.java b/examples/TestUnicode.java new file mode 100644 index 0000000..1bb34b5 --- /dev/null +++ b/examples/TestUnicode.java @@ -0,0 +1,60 @@ +import java.io.*; +import jcifs.smb.*; +import jcifs.util.*; + +public class TestUnicode { + static SmbFile dir; + + public static void mkobj( String name ) throws Exception { + int r = (int)(Math.random() * 100.0); + if( r < 50 ) { + SmbFile d = new SmbFile( dir.getParent(), dir.getName() + "/" + name ); + d.mkdir(); + if( r < 15 ) { + dir = d; + } + } else { + SmbFileOutputStream out = new SmbFileOutputStream( dir.getParent() + "/" + dir.getName() + "/" + name ); + out.close(); + } + } + + public static void main( String argv[] ) throws Exception { + if( argv.length < 1 ) { + throw new IllegalArgumentException( "Must provide path to directory in which to run test" ); + } + FileInputStream in = new FileInputStream( "data" ); + byte[] b = new byte[4096]; + int n = in.read( b ); + String data = new String( b, 0, n, "UTF-8" ); + char[] d = data.toCharArray(); + + dir = new SmbFile( argv[0] + "/TestUnicode" ); + try { + dir.delete(); + } catch( SmbException se ) { + se.printStackTrace(); + } + dir.mkdir(); + + int i, s, max = 8; + for( i = s = 0; i < d.length; i++ ) { + switch (d[i]) { + case '"': case '/': case '\\': case '[': case ']': + case ':': case '|': case '<': case '>': case '=': + case ';': case ',': case '*': case '?': case '\n': + d[i] = '_'; + } + if(Character.isWhitespace( d[i] )) { + if( i == s ) { + s++; + } + if( i > (s + max)) { + String name = new String( d, s, i - s ); + mkobj( name ); + s = i + 1; + } + } + } + } +} diff --git a/examples/ThreadedNbtQuery.java b/examples/ThreadedNbtQuery.java new file mode 100644 index 0000000..022e3fa --- /dev/null +++ b/examples/ThreadedNbtQuery.java @@ -0,0 +1,38 @@ +import jcifs.netbios.*; + +public class ThreadedNbtQuery { + + static class QThread extends Thread { + String name; + + QThread( String name ) { + this.name = name; + } + + public void run() { + try { + yield(); + System.out.println( getName() + ": started" ); + NbtAddress.getByName( name ); + System.out.println( getName() + ": done" ); + } catch( Exception x ) { + x.printStackTrace(); + } + } + } + + public static void main(String[] argv) throws Exception { + if( argv.length < 2 ) { + System.out.println( "java ThreadedNbtQuery name [name [name [...]]]" ); + return; + } + + QThread[] t = new QThread[argv.length]; + for( int i = 0; i < argv.length; i++ ) { + t[i] = new QThread( argv[i] ); + } + for( int j = 0; j < argv.length; j++ ) { + t[j].start(); + } + } +} diff --git a/examples/ThreadedSmbCrawler.java b/examples/ThreadedSmbCrawler.java new file mode 100644 index 0000000..1d61b20 --- /dev/null +++ b/examples/ThreadedSmbCrawler.java @@ -0,0 +1,136 @@ +/* examples for the jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * 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. + */ + +import jcifs.smb.SmbFile; +import java.util.LinkedList; +import java.util.ListIterator; +import java.net.MalformedURLException; +import java.io.IOException; + +public class ThreadedSmbCrawler { + + static int workingThreads = 0; + + class DirEntry { + SmbFile dir; + int depth; + + DirEntry( SmbFile dir, int depth ) { + this.dir = dir; + this.depth = depth; + } + } + + class SmbCrawlerThread extends Thread { + + StringBuffer sb = new StringBuffer(); + + public void run() { + while( true ) { + try { + DirEntry e; + + synchronized( dirList ) { + while( dirList.isEmpty() ) { +//System.err.println( "workingThreads=" + workingThreads ); + if( workingThreads == 0 ) { + return; // done + } + dirList.wait( 2000 ); + } + e = (DirEntry)dirList.remove( 0 ); + if( e.depth == 0 ) { + continue; + } + workingThreads++; + } + + SmbFile[] l = e.dir.listFiles(); + + int n = maxDepth - e.depth; + + for(int i = 0; l != null && i < l.length; i++ ) { + try { + sb.setLength( 0 ); + for( int k = 0; k < n; k++ ) { + sb.append( " " ); + } + SmbFile d = l[i]; + System.err.println( sb.append( d )); + if( d.isDirectory() ) { + synchronized( dirList ) { + dirList.add( new DirEntry( d, e.depth - 1 )); + dirList.notify(); + } + } + } catch( IOException ioe ) { + ioe.printStackTrace(); + } + } + synchronized( dirList ) { + workingThreads--; + } + } catch( Exception x ) { + synchronized( dirList ) { + workingThreads--; + } + x.printStackTrace(); + } + } + } + } + + LinkedList dirList; + int maxDepth, numThreads; + Thread[] threads; + + ThreadedSmbCrawler( String dir, int maxDepth, int numThreads ) throws Exception { + this.maxDepth = maxDepth; + this.numThreads = numThreads; + threads = new Thread[numThreads]; + dirList = new LinkedList(); + dirList.add( new DirEntry( new SmbFile( dir ), maxDepth )); + } + + long go() throws Exception { + int i; + long start = System.currentTimeMillis(); + + for( i = 0; i < numThreads; i++ ) { + threads[i] = new SmbCrawlerThread(); + threads[i].start(); + } + for( i = 0; i < numThreads; i++ ) { + threads[i].join(); + } + + return System.currentTimeMillis() - start; + } + + public static void main(String[] argv) throws Exception { + ThreadedSmbCrawler tsc; + + if( argv.length < 3 ) { + System.err.println( "usage: ThreadedSmbCrawler dir depth numThreads" ); + System.exit( 1 ); + } + + tsc = new ThreadedSmbCrawler( argv[0], Integer.parseInt( argv[1] ), Integer.parseInt( argv[2] )); + System.err.println( "Crawling Complete: " + (tsc.go() / 1000) + "sec" ); + } +} diff --git a/examples/ThreadedUniQuery.java b/examples/ThreadedUniQuery.java new file mode 100644 index 0000000..5c51da3 --- /dev/null +++ b/examples/ThreadedUniQuery.java @@ -0,0 +1,50 @@ +import java.net.UnknownHostException; +import jcifs.*; + +public class ThreadedUniQuery { + + static class QThread extends Thread { + String name; + + QThread( String name ) { + super( name + "-thread" ); + this.name = name; + } + + public void run() { + try { + System.out.println( getName() + ": started" ); + for( int i = 0; i < 15; i++ ) { + Thread.sleep( (long)(Math.random() * 1000L )); + try { + UniAddress.getByName( name, true ); + } catch( UnknownHostException uhe ) { + uhe.printStackTrace(); + } + } + System.out.println( getName() + ": done" ); + } catch( Exception x ) { + x.printStackTrace(); + } + } + } + + public static void main(String[] argv) throws Exception { + if( argv.length < 2 ) { + System.out.println( "java ThreadedUniQuery name [name [name [...]]]" ); + return; + } + + QThread[] t = new QThread[argv.length]; + for( int i = 0; i < argv.length; i++ ) { + t[i] = new QThread( argv[i] ); + } + for( int j = 0; j < argv.length; j++ ) { + t[j].start(); + } + for( int j = 0; j < argv.length; j++ ) { + t[j].join(); + } + Runtime.getRuntime().exit(0); + } +} diff --git a/examples/Torture1.java b/examples/Torture1.java new file mode 100644 index 0000000..aa54852 --- /dev/null +++ b/examples/Torture1.java @@ -0,0 +1,102 @@ +import java.io.*; +import jcifs.smb.*; +import java.util.*; + +class Worker extends Thread { + + Torture1 t; + Exception e; + + Worker( Torture1 t ) { + this.t = t; + e = null; + } + public void run() { + try { + t.torture(); + } catch( Exception e ) { + this.e = e; + } + } +} + +public class Torture1 { + + Properties prp; + + Torture1( Properties prp ) { + this.prp = prp; + } + + void compare( SmbFile f1, SmbFile f2 ) throws Exception { + if( f1.isDirectory() && f2.isDirectory() ) { + SmbFile[] dirents = f1.listFiles(); + SmbFile f; + for( int i = 0; i < dirents.length; i++ ) { + f = new SmbFile( f2, dirents[i].getName() ); + compare( dirents[i], f ); + } + } + if( f1.isDirectory() != f2.isDirectory() ) { + System.err.println( "directory comparison failed" ); + } + if( f1.isFile() != f2.isFile() ) { + System.err.println( "file comparison failed" ); + } + if( f1.getType() != f2.getType() ) { + System.err.println( "type comparison failed" ); + } + if( f1.getName().equals( f2.getName() ) == false ) { + System.err.println( "name comparison failed: " + f1.getName() + " " + f2.getName() ); + } + if( f1.length() != f2.length() ) { + System.err.println( "length comparison failed: " + f1.length() + " " + f2.length() ); + } + } + + void torture() throws Exception { + String domain, username, password, server, share, directory; + NtlmPasswordAuthentication ntlm; + + domain = prp.getProperty( "torture.dst.domain" ); + username = prp.getProperty( "torture.dst.username" ); + password = prp.getProperty( "torture.dst.password" ); + + ntlm = new NtlmPasswordAuthentication( domain, username, password ); + + server = prp.getProperty( "torture.dst.server" ); + share = prp.getProperty( "torture.dst.share" ); + directory = prp.getProperty( "torture.dst.directory" ); + + SmbFile dst = new SmbFile( "smb://", ntlm ); + dst = new SmbFile( dst, server ); + dst = new SmbFile( dst, share ); + dst = new SmbFile( dst, directory ); + + SmbFile src = new SmbFile( prp.getProperty( "torture.src.url" )); + +System.err.println( src + " --> " + dst ); +System.in.read(); + + if( dst.exists() ) { + dst.delete(); + } + src.copyTo( dst ); +System.err.println( "CopyTo done" ); +System.in.read(); + compare( src, dst ); +System.err.println( "Test Complete" ); + } + + public static void main( String[] argv ) throws Exception { + Properties prp = new Properties(); + prp.load( new FileInputStream( "torture.prp" )); + Torture1 t = new Torture1( prp ); + Worker w = new Worker( t ); + w.start(); + w.join(); + if( w.e != null ) { + throw w.e; + } + } +} diff --git a/examples/Torture2.java b/examples/Torture2.java new file mode 100644 index 0000000..597319f --- /dev/null +++ b/examples/Torture2.java @@ -0,0 +1,102 @@ +import java.io.*; +import jcifs.smb.*; +import jcifs.util.Hexdump; +import java.util.*; + +public class Torture2 extends Thread { + + SmbFile from, to; + + Torture2( String from, String to ) throws Exception { + this.from = new SmbFile( from ); + this.to = new SmbFile( to ); + } + + public void run() { + try { + copyAndVerify(); + } catch( Exception e ) { + e.printStackTrace(); + } + } + + void compare( SmbFile f1, SmbFile f2 ) throws Exception { +//System.err.println( f1.getName() + " | " + f2.getName() ); +try { + if( f1.isDirectory() && f2.isDirectory() ) { + SmbFile[] dirents = f1.listFiles(); + SmbFile f; + for( int i = 0; i < dirents.length; i++ ) { + f = new SmbFile( f2, dirents[i].getName() ); +//System.err.println( f2 + " + " + dirents[i].getName() + " = " + f + ": isDirectory=" + f.isDirectory() ); + compare( dirents[i], f ); + } + } + if( f1.isDirectory() != f2.isDirectory() ) { + System.err.println( "directory comparison failed: " + f1.getName() + ": " + f1.isDirectory() + " " + f2.isDirectory() ); + } + if( f1.isFile() != f2.isFile() ) { + System.err.println( "file comparison failed: " + f1.getName() + ": " + f1.isFile() + " " + f2.isFile() ); + } + if( f1.getType() != f2.getType() ) { + System.err.println( "type comparison failed: " + f1.getName() + " " + f2.getName() ); + } + if( f1.getName().equals( f2.getName() ) == false ) { + System.err.println( "name comparison failed: " + f1.getName() + " " + f2.getName() ); + } + if( f1.length() != f2.length() ) { + System.err.println( "length comparison failed: " + f1.getName() + ": " + f1.length() + " " + f2.length() ); + } + if( f1.getAttributes() != f2.getAttributes() ) { + System.err.println( "attribute comparison failed: " + f1.getName() + ": " + Hexdump.toHexString( f1.getAttributes(), 4 ) + " " + Hexdump.toHexString( f2.getAttributes(), 4 )); + } + if( Math.abs( f1.createTime() - f2.createTime() ) > 1000 ) { + System.err.println( "create time comparison failed: " + f1.getName() + ": " + f1.createTime() + " " + f2.createTime() ); + } + if( Math.abs( f1.lastModified() - f2.lastModified() ) > 1000 ) { + System.err.println( "last modified comparison failed: " + f1.getName() + ": " + f1.lastModified() + " " + f2.lastModified() ); + } +} catch( Exception x ) { + System.err.println( "Exception comparing: " + f1 + " | " + f2 ); + x.printStackTrace(); +} + } + + void copyAndVerify() throws Exception { + from.copyTo( to ); + compare( from, to ); + } + + public static void main( String[] argv ) throws Exception { + Properties prp; + Torture2[] threads; + String from, to; + int i; + + if( argv.length < 1 ) { + System.err.println( "Torture2 " ); + System.exit( 1 ); + } + + prp = new Properties(); + prp.load( new FileInputStream( argv[0] )); + + threads = new Torture2[10]; + + for( i = 0; i < 10; i++ ) { + from = prp.getProperty( "thread." + i + ".from.url" ); + to = prp.getProperty( "thread." + i + ".to.url" ); + if( from == null || to == null ) { + break; + } + threads[i] = new Torture2( from, to ); + threads[i].start(); + Thread.sleep( 12345 ); + } + while( i-- > 0 ) { + threads[i].join(); + } + System.err.println( "Test complete" ); + } +} + diff --git a/examples/TortureTest5.java b/examples/TortureTest5.java new file mode 100644 index 0000000..dacf92c --- /dev/null +++ b/examples/TortureTest5.java @@ -0,0 +1,36 @@ +import jcifs.UniAddress; +import java.util.Enumeration; + +public class TortureTest5 extends Thread { + + String name; + + TortureTest5( String name ) { + this.name = name; + } + + public void run() { + try { + System.out.println( UniAddress.getByName( name )); + } catch( Exception e ) { + e.printStackTrace(); + } + } + + public static void main( String[] argv ) throws Exception { + // jcifs.util.Config.setProperty( "retryCount", "1" ); + // jcifs.util.Config.setProperty( "soTimeout", "1000" ); + + Thread[] threads = new Thread[30]; + for( int i = 0; i < argv.length; i++ ) { + threads[i] = new TortureTest5( argv[i] ); + } + for( int t = 0; t < argv.length; t++ ) { + threads[t].start(); + } + for( int j = 0; j < argv.length; j++ ) { + threads[j].join(); + } + System.exit( 0 ); + } +} diff --git a/examples/TransactNamedPipe.java b/examples/TransactNamedPipe.java new file mode 100644 index 0000000..f0b7d42 --- /dev/null +++ b/examples/TransactNamedPipe.java @@ -0,0 +1,36 @@ +import jcifs.smb.SmbNamedPipe; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; + +public class TransactNamedPipe { + + public static void main( String[] argv ) throws Exception { + + if( argv.length < 2 ) { + throw new IllegalArgumentException( + "args: " ); + } + + byte[] b = new byte[65535]; + FileInputStream fin = new FileInputStream( argv[1] ); + FileOutputStream fos = new FileOutputStream( argv[2] ); + + SmbNamedPipe pipe = new SmbNamedPipe( argv[0], + SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_TRANSACT ); + OutputStream out = pipe.getNamedPipeOutputStream(); + InputStream in = pipe.getNamedPipeInputStream(); + + int n = fin.read( b ); + System.out.println( "writing " + n + " bytes" ); + out.write( b, 0, n ); + n = in.read(b); + System.out.println( "read " + n + " bytes" ); + fos.write(b, 0, n ); + + fin.close(); + fos.close(); + out.close(); + } +} diff --git a/examples/U2.java b/examples/U2.java new file mode 100644 index 0000000..7939352 --- /dev/null +++ b/examples/U2.java @@ -0,0 +1,10 @@ +import jcifs.dcerpc.*; +import jcifs.util.*; + +public class U2 { + + public static void main( String[] argv ) throws Exception { + UUID uuid = new UUID(argv[0]); + System.out.println(uuid.toString()); + } +} diff --git a/examples/URLTest.java b/examples/URLTest.java new file mode 100644 index 0000000..bcc1ec6 --- /dev/null +++ b/examples/URLTest.java @@ -0,0 +1,31 @@ +import java.net.*; +import java.util.*; + +public class URLTest { + + public static void main( String[] argv ) throws Exception { + URL url; + + jcifs.Config.registerSmbURLHandler(); + + if( argv.length > 2 ) { + url = new URL( new URL( new URL( argv[0] ), argv[1] ), argv[2] ); + } else if( argv.length > 1 ) { + url = new URL( new URL( argv[0] ), argv[1] ); + } else { + url = new URL( argv[0] ); + } + System.out.println( " authority: " + url.getAuthority() ); + System.out.println( " file: " + url.getFile() ); + System.out.println( " host: " + url.getHost() ); + System.out.println( " port: " + url.getPort() ); + System.out.println( " path: " + url.getPath() ); + System.out.println( " query: " + url.getQuery() ); + System.out.println( " ref: " + url.getRef() ); + System.out.println( " userinfo: " + url.getUserInfo() ); + System.out.println( "externalform: " + url.toExternalForm() ); + System.out.println( " string: " + url.toString() ); + + System.exit( 0 ); + } +} diff --git a/examples/UrlReader.java b/examples/UrlReader.java new file mode 100644 index 0000000..e724d68 --- /dev/null +++ b/examples/UrlReader.java @@ -0,0 +1,41 @@ +import java.net.*; +import java.io.*; + +public class UrlReader extends Thread { + + URL url; + byte[] buf; + + public UrlReader( String u, int bufsiz ) throws Exception { + url = new URL( u ); + buf = new byte[bufsiz]; + } + + public void run() { + try { + InputStream in = url.openStream(); + int n; + while ((n = in.read( buf )) > 0) { + System.out.write( buf, 0, n ); + } + in.close(); + System.err.println( url + " read complete" ); + } catch( Exception ex ) { + ex.printStackTrace( System.err ); + } + } + + public static void main( String[] args ) throws Exception { + UrlReader[] readers = new UrlReader[args.length]; + + jcifs.Config.registerSmbURLHandler(); + + int i; + for( i = 0; i < args.length; i++) { + readers[i] = new UrlReader( args[i], (i + 1) * 128 ); + } + for( i = 0; i < args.length; i++) { + readers[i].start(); + } + } +} diff --git a/examples/VerifyGuest.java b/examples/VerifyGuest.java new file mode 100644 index 0000000..8ad76e0 --- /dev/null +++ b/examples/VerifyGuest.java @@ -0,0 +1,27 @@ +import jcifs.netbios.NbtAddress; +import jcifs.smb.*; +import java.util.Date; + +public class VerifyGuest { + + public static void list( SmbFile dir ) { + try { + long t1 = System.currentTimeMillis(); + SmbFile[] files = dir.listFiles(); + long t2 = System.currentTimeMillis() - t1; + + for( int i = 0; i < files.length; i++ ) { + System.out.print( " " + files[i].getName() ); + } + System.out.println(); + System.out.println( files.length + " files in " + t2 + "ms" ); + } catch( Exception e ) { + e.printStackTrace(); + } + } + + public static void main( String[] argv ) throws Exception { + list( new SmbFile( "smb://miallen2/" )); + list( new SmbFile( "smb://miallen2/pub/", new NtlmPasswordAuthentication( "dom", "user", "pass" ))); + } +} diff --git a/examples/VerifyIO.java b/examples/VerifyIO.java new file mode 100644 index 0000000..5f68301 --- /dev/null +++ b/examples/VerifyIO.java @@ -0,0 +1,76 @@ +import java.net.MalformedURLException; +import jcifs.smb.*; +import java.io.*; + +public class VerifyIO { + + static File get( SmbFile f0 ) throws Exception { + int i; + File f1; + byte[] buf = new byte[8192]; + + f1 = new File( f0.getName() ); + FileOutputStream out = new FileOutputStream( f1 ); + SmbFileInputStream in = new SmbFileInputStream( f0 ); + + while(( i = in.read( buf )) > 0 ) { + out.write( buf, 0, i ); + System.err.print( '.' ); + } + + in.close(); + out.close(); + + return f1; + } + static void put( SmbFile f2 ) throws Exception { + int i; + byte[] buf = new byte[8192]; + + FileInputStream in = new FileInputStream( f2.getName() ); + SmbFileOutputStream out = new SmbFileOutputStream( f2 ); + + while(( i = in.read( buf )) > 0 ) { + out.write( buf, 0, i ); + System.err.print( '-' ); + } + + in.close(); + out.close(); + } + + public static void main(String[] argv) throws Exception { + BufferedReader in; + String name; + + if( argv.length < 2 ) { + System.err.println( "Must provide file of SMB URLs and destination directory" ); + System.exit( 1 ); + } + + in = new BufferedReader( new FileReader( argv[0] )); + while(( name = in.readLine() ) != null ) { + SmbFile f0, f2; + File f1; + + System.err.print( name + ": " ); + f0 = new SmbFile( name ); + f1 = get( f0 ); + + if( f0.length() != f1.length() ) { + throw new RuntimeException( "File lengths do not match: f0=" + f0.length() + ",f1=" + f1.length() ); + } + + f2 = new SmbFile( argv[1] + "/" + f0.getName() ); + put( f2 ); + + if( f1.length() != f2.length() ) { + throw new RuntimeException( "File lengths do not match: f1=" + f1.length() + ",f2=" + f2.length() ); + } + + f1.delete(); + System.err.println( " ok" ); + } + } +} + diff --git a/examples/VerifyReads.java b/examples/VerifyReads.java new file mode 100644 index 0000000..d845cb5 --- /dev/null +++ b/examples/VerifyReads.java @@ -0,0 +1,78 @@ +import java.net.MalformedURLException; +import jcifs.smb.*; +import java.io.*; + +public class VerifyReads { + + int maxDepth; + byte[] buf = new byte[8192]; + + VerifyReads( int maxDepth ) { + this.maxDepth = maxDepth; + } + + void mkdir( File dir ) { + if( dir != null && !dir.exists() ) { + mkdir( dir.getParentFile() ); + dir.mkdir(); + } + } + + void copy( SmbFile f, String path, int depth ) throws MalformedURLException, IOException { + int i, d; + File localFile, dir; + SmbFile[] list; + + if( depth == 0 ) { + return; + } + + localFile = new File( path + "/" + f.getName() ); + d = f.getName().lastIndexOf( '.' ); + + if( f.isDirectory() ) { + + list = f.listFiles(); + + for( i = 0; i < list.length; i++ ) { + copy( list[i], path + "/" + f.getName(), depth - 1 ); + } + } else if( d > 1 && f.getName().substring( d ).equalsIgnoreCase( ".ini" )) { + + mkdir( new File( path )); + + SmbFileInputStream in = new SmbFileInputStream( f ); + FileOutputStream out = new FileOutputStream( localFile ); + + while(( i = in.read( buf )) > 0 ) { + out.write( buf, 0, i ); + } + + in.close(); + out.close(); + } + } + + public static void main(String[] argv) throws Exception { + VerifyReads cd; + SmbFile top; + int depth; + + if( argv.length < 2 ) { + System.err.println( "Must specify ini directory location (e.g. smb://mydom\\;user:pass@nyc-19b9/apps) followd by the maximum traversal depth"); + System.exit( 1 ); + } + + depth = Integer.parseInt( argv[1] ); + cd = new VerifyReads( depth ); + top = new SmbFile( argv[0] ); + + if( !top.isDirectory() ) { + System.err.println( "The path specified is not a directory" ); + System.exit( 1 ); + } + + cd.copy( top, ".", depth ); + } +} + diff --git a/examples/WaitNamedPipe.java b/examples/WaitNamedPipe.java new file mode 100644 index 0000000..682a967 --- /dev/null +++ b/examples/WaitNamedPipe.java @@ -0,0 +1,34 @@ +import jcifs.smb.SmbNamedPipe; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; + +public class WaitNamedPipe { + + public static void main( String[] argv ) throws Exception { + + if( argv.length < 2 ) { + throw new IllegalArgumentException( "args: " ); + } + + byte[] b = new byte[65535]; + FileInputStream fin = new FileInputStream( argv[1] ); + FileOutputStream fos = new FileOutputStream( argv[2] ); + + SmbNamedPipe pipe = new SmbNamedPipe( argv[0], SmbNamedPipe.PIPE_TYPE_RDWR ); + OutputStream out = pipe.getNamedPipeOutputStream(); + InputStream in = pipe.getNamedPipeInputStream(); + + int n = fin.read( b ); + System.out.println( "writing " + n + " bytes" ); + out.write( b, 0, n ); + n = in.read(b); + System.out.println( "read " + n + " bytes" ); + fos.write(b, 0, n ); + + fin.close(); + fos.close(); + out.close(); + } +} diff --git a/examples/data b/examples/data new file mode 100644 index 0000000..86cc0b8 --- /dev/null +++ b/examples/data @@ -0,0 +1,17 @@ +Unë mund të ha qelq dhe nuk më gjen gjë +⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌ +Mi povas manĝi vitron, ĝi ne damaĝas min +yoyo seti @ home Tarzan + Jane Barnum & Baley +J'peux bouffer d'la vitre, ça m'fa pas mal +Dji pou magnî do vêre, çoula m' freut nén må +которая состоится 10-12 марта 1997 года в Майнце в Германии +Pot să mănânc sticlă și ea nu mă rănește +Tá mé in ann gloine a ithe; Ní chuireann sé isteach nó amach orm +Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα +Èg get borðað gler, það meiðir mig ekki +Я можу їсти шкло, й воно мені не пошкодить +אני יכול לאכול זכוכית וזה לא מזיק לי +Mo lè je̩ dígí, kò ní pa mí lára +Μπορώ να φάω σπασμένα να γυαλιά χωρίς να πάθω τίποτα +Èg get borðað gler, það meiðir mig ekki +Я можу їсти шкло, й воно мені не пошкодить diff --git a/examples/jcifs.prp b/examples/jcifs.prp new file mode 100644 index 0000000..de66346 --- /dev/null +++ b/examples/jcifs.prp @@ -0,0 +1,20 @@ +jcifs.smb.client.domain = mydom +jcifs.smb.client.username = miallen +jcifs.smb.client.password = p@ssw0rd +jcifs.resolveOrder = WINS,DNS +jcifs.netbios.wins = 196.22.20.21,164.25.87.5 +jcifs.smb.client.signingPreferred = true +;jcifs.util.loglevel = 10 +;jcifs.netbios.cachePolicy = 30 +;jcifs.smb.client.maxBuffers = 20 +;jcifs.smb.client.soTimeout = 4000 +;jcifs.smb.client.responseTimeout = 15000 +;jcifs.smb.client.maxMpxCount = 10 +;jcifs.smb.client.attrExpirationPeriod = 0 +;jcifs.smb.client.useUnicode = false +;jcifs.smb.client.disablePlainTextPasswords = false +;jcifs.smb.client.snd_buf_size = 8192 +;jcifs.smb.client.useNTSmbs = false +;jcifs.smb.client.useBatching = false +;jcifs.smb.client.listSize = 1200 +;jcifs.smb.client.listCount = 15 diff --git a/examples/pipes/callnp.c b/examples/pipes/callnp.c new file mode 100644 index 0000000..c29c220 --- /dev/null +++ b/examples/pipes/callnp.c @@ -0,0 +1,123 @@ +/* examples for the jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * 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. + */ + +/* callnp.c - Call a Named Pipe + */ + +#include +#include +#include + +int +hexstrtoi(const char *str) +{ + int i; + for (i = 0; str[i] != '\0'; i++) { + if (str[i] != 'x' && (str[i] < 48 || str[i] > 57)) { + errno = 1; + return 0; + } + } + return (int)strtol(str, NULL, 16); +} + +int +main(int argc, char *argv[]) +{ + int i; + int bufferSize, timeout, bytesRead; + char *target, *send_buf, *recv_buf; + HANDLE inFile, outFile; + + inFile = NULL; + outFile = NULL; + bufferSize = 65535; + bytesRead = 0; + + if (argc == 1 || argv[1][1] == '\?') { + printf("defaults\r\n"); + printf(" inFile = \r\n"); + printf(" outFile = \r\n"); + printf(" bufferSize = 65535\r\n"); + + printf("\r\ncallnp \\\\server\\pipe\\name /I inFile /O outFile /B bufferSize\r\n"); + + return 0; + } + + if(argv[1][0] != '\\' && argv[1][1] != '\\') { + printf("Error: must specify target\r\n"); + } + target = argv[1]; + for(i = 2; i < argc; i++) { + if(argv[i][0] != '/') { + printf("Error: invalid switch\r\n"); + } + errno = 0; + switch(argv[i++][1]) { + case 'I': + inFile = CreateFile(argv[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(outFile == INVALID_HANDLE_VALUE) { + printf("Error: cannot open inFile: %s\r\n", argv[i]); + return 0; + } + break; + case 'O': + outFile = CreateFile(argv[i], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if(outFile == INVALID_HANDLE_VALUE) { + printf("Error: cannot open outFile: %s\r\n", argv[i]); + return 0; + } + break; + case 'B': + bufferSize = atoi(argv[i]); + break; + default: + printf("Error: no such option\r\n"); + return 0; + } + if(errno) { + printf("Error: values must be in hex.\r\n"); + return 0; + } + } + send_buf = malloc(bufferSize); + recv_buf = malloc(bufferSize); + if(send_buf == NULL || recv_buf == NULL) { + printf("Error: failed to allocate buffers\r\n"); + return 0; + } + if(inFile != NULL && ReadFile(inFile, send_buf, bufferSize, &bytesRead, NULL) == 0) { + printf("Error: failed to read from inFile\r\n"); + return 0; + } + if (WaitNamedPipe(target, NMPWAIT_WAIT_FOREVER) == 0) { + printf("Error: WaitNamedPipe operation failed: %u\r\n", GetLastError()); + return 0; + } + if (CallNamedPipe(target, send_buf, bytesRead, recv_buf, bufferSize, &bytesRead, NMPWAIT_WAIT_FOREVER) == 0) { + printf("Error: CallNamedPipe operation failed: %u\r\n", GetLastError()); + return 0; + } + if(outFile != NULL && WriteFile(outFile, recv_buf, bytesRead, &bytesRead, NULL) == 0) { + printf("Error: failed to write to outFile\r\n"); + } + printf("Success: operation performed successfully\r\n"); + return 1; +} + diff --git a/examples/pipes/createf.c b/examples/pipes/createf.c new file mode 100644 index 0000000..24421fb --- /dev/null +++ b/examples/pipes/createf.c @@ -0,0 +1,208 @@ +/* examples for the jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * 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. + */ + +/* createf.c - Create a file with the CreateFile call. + */ + + +#include +#include +#include + +#define hexstrtoui(s) ((int)strtoul((s), NULL, 16)) + +int +main(int argc, char *argv[]) +{ + int i; + int desiredAccess, shareMode, disposition, flags, bufferSize, bytesRead; + char *target, *buf; + HANDLE h, inFile, outFile; + + inFile = NULL; + outFile = NULL; + desiredAccess = GENERIC_READ; + shareMode = 0; + disposition = CREATE_ALWAYS; + flags = FILE_ATTRIBUTE_NORMAL; + bufferSize = 65535; + + if (argc == 1 || argv[1][1] == '\?') { + + /* dwDesiredAccess + */ + printf("dwDesiredAccess\r\n"); + printf(" 0x%08x GENERIC_READ\r\n", GENERIC_READ); + printf(" 0x%08x GENERIC_WRITE\r\n", GENERIC_WRITE); + printf(" 0x%08x DELETE\r\n", DELETE); + printf(" 0x%08x READ_CONTROL\r\n", READ_CONTROL); + printf(" 0x%08x WRITE_DAC\r\n", WRITE_DAC); + printf(" 0x%08x WRITE_OWNER\r\n", WRITE_OWNER); + printf(" 0x%08x SYNCHRONIZE\r\n", SYNCHRONIZE); + printf(" 0x%08x STANDARD_RIGHTS_REQUIRED\r\n", STANDARD_RIGHTS_REQUIRED); + printf(" 0x%08x STANDARD_RIGHTS_READ\r\n", STANDARD_RIGHTS_READ); + printf(" 0x%08x STANDARD_RIGHTS_WRITE\r\n", STANDARD_RIGHTS_WRITE); + printf(" 0x%08x STANDARD_RIGHTS_EXECUTE\r\n", STANDARD_RIGHTS_EXECUTE); + printf(" 0x%08x STANDARD_RIGHTS_ALL\r\n", STANDARD_RIGHTS_ALL); + printf(" 0x%08x SPECIFIC_RIGHTS_ALL\r\n", SPECIFIC_RIGHTS_ALL); + printf(" 0x%08x ACCESS_SYSTEM_SECURITY\r\n", ACCESS_SYSTEM_SECURITY); + printf(" 0x%08x MAXIMUM_ALLOWED\r\n", MAXIMUM_ALLOWED); + printf(" 0x%08x GENERIC_EXECUTE\r\n", GENERIC_EXECUTE); + printf(" 0x%08x GENERIC_ALL\r\n", GENERIC_ALL); + /* dwShareMode + */ + printf("dwShareMode\n"); + printf(" 0x%08x FILE_SHARE_DELETE\r\n", FILE_SHARE_DELETE); + printf(" 0x%08x FILE_SHARE_READ\r\n", FILE_SHARE_READ); + printf(" 0x%08x FILE_SHARE_WRITE\r\n", FILE_SHARE_WRITE); + printf(" 0x%08x the file cannot be shared\r\n", 0); + /* dwCreateDisposition + */ + printf("dwCreateDisposition\r\n"); + printf(" 0x%08x CREATE_NEW\r\n", CREATE_NEW); + printf(" 0x%08x CREATE_ALWAYS\r\n", CREATE_ALWAYS); + printf(" 0x%08x OPEN_EXISTING\r\n", OPEN_EXISTING); + printf(" 0x%08x OPEN_ALWAYS\r\n", OPEN_ALWAYS); + printf(" 0x%08x TRUNCATE_EXISTING\r\n", TRUNCATE_EXISTING); + /* dwFlagsAndAttributes + */ + printf("dwFlagsAndAttributes\r\n"); + printf(" 0x%08x FILE_ATTRIBUTE_ARCHIVE\r\n", FILE_ATTRIBUTE_ARCHIVE); + printf(" 0x%08x FILE_ATTRIBUTE_ENCRYPTED\r\n", FILE_ATTRIBUTE_ENCRYPTED); + printf(" 0x%08x FILE_ATTRIBUTE_HIDDEN\r\n", FILE_ATTRIBUTE_HIDDEN); + printf(" 0x%08x FILE_ATTRIBUTE_NORMAL\r\n", FILE_ATTRIBUTE_NORMAL); + printf(" 0x%08x FILE_ATTRIBUTE_NOT_CONTENT_INDEXED\r\n", FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); + printf(" 0x%08x FILE_ATTRIBUTE_OFFLINE\r\n", FILE_ATTRIBUTE_OFFLINE); + printf(" 0x%08x FILE_ATTRIBUTE_READONLY\r\n", FILE_ATTRIBUTE_READONLY); + printf(" 0x%08x FILE_ATTRIBUTE_SYSTEM\r\n", FILE_ATTRIBUTE_SYSTEM); + printf(" 0x%08x FILE_ATTRIBUTE_TEMPORARY\r\n", FILE_ATTRIBUTE_TEMPORARY); + + printf(" 0x%08x FILE_FLAG_WRITE_THROUGH\r\n", FILE_FLAG_WRITE_THROUGH); + printf(" 0x%08x FILE_FLAG_OVERLAPPED\r\n", FILE_FLAG_OVERLAPPED); + printf(" 0x%08x FILE_FLAG_NO_BUFFERING\r\n", FILE_FLAG_NO_BUFFERING); + printf(" 0x%08x FILE_FLAG_RANDOM_ACCESS\r\n", FILE_FLAG_RANDOM_ACCESS); + printf(" 0x%08x FILE_FLAG_SEQUENTIAL_SCAN\r\n", FILE_FLAG_SEQUENTIAL_SCAN); + printf(" 0x%08x FILE_FLAG_DELETE_ON_CLOSE\r\n", FILE_FLAG_DELETE_ON_CLOSE); + printf(" 0x%08x FILE_FLAG_BACKUP_SEMANTICS\r\n", FILE_FLAG_BACKUP_SEMANTICS); + printf(" 0x%08x FILE_FLAG_POSIX_SEMANTICS\r\n", FILE_FLAG_POSIX_SEMANTICS); + + printf(" 0x%08x FILE_FLAG_OPEN_REPARSE_POINT\r\n", FILE_FLAG_OPEN_REPARSE_POINT); + printf(" 0x%08x FILE_FLAG_OPEN_NO_RECALL\r\n", FILE_FLAG_OPEN_NO_RECALL); + printf(" 0x%08x SECURITY_ANONYMOUS\r\n", SECURITY_ANONYMOUS); + printf(" 0x%08x SECURITY_IDENTIFICATION\r\n", SECURITY_IDENTIFICATION); + printf(" 0x%08x SECURITY_IMPERSONATION\r\n", SECURITY_IMPERSONATION); + printf(" 0x%08x SECURITY_DELEGATION\r\n", SECURITY_DELEGATION); + printf(" 0x%08x SECURITY_CONTEXT_TRACKING\r\n", SECURITY_CONTEXT_TRACKING); + printf(" 0x%08x SECURITY_EFFECTIVE_ONLY\r\n", SECURITY_EFFECTIVE_ONLY); + + printf("defaults\r\n"); + printf(" dwDesiredAccess = GENERIC_READ\r\n"); + printf(" dwShareMode = FILE_SHARE_READ\r\n"); + printf(" dwCreateDisposition = CREATE_ALWAYS\r\n"); + printf(" dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL\r\n"); + printf(" inFile = none\r\n"); + printf(" outFile = none\r\n"); + printf(" bufferSize = 65535\r\n"); + + printf("\r\ncreatef \\\\server\\share\\path /A access /S share /D disposition /F flags /I inFile /O outFile /B bufferSize\r\n"); + + return 0; + } + + if(argv[1][0] != '\\' && argv[1][1] != '\\') { + printf("Error: must specify target\r\n"); + } + target = argv[1]; + for(i = 2; i < argc; i++) { + if(argv[i][0] != '/') { + printf("Error: invalid switch\r\n"); + } + errno = 0; + switch(argv[i++][1]) { + case 'A': + desiredAccess = hexstrtoui(&argv[i][2]); + break; + case 'S': + shareMode = hexstrtoui(argv[i]); + break; + case 'D': + disposition = hexstrtoui(argv[i]); + break; + case 'F': + flags = hexstrtoui(argv[i]); + break; + case 'I': + inFile = CreateFile(argv[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(inFile == INVALID_HANDLE_VALUE) { + printf("Error: cannot open inFile: %s\r\n", argv[i]); + CloseHandle(outFile); + return 0; + } + break; + case 'O': + outFile = CreateFile(argv[i], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if(outFile == INVALID_HANDLE_VALUE) { + printf("Error: cannot open outFile: %s\r\n", argv[i]); + CloseHandle(inFile); + return 0; + } + break; + default: + printf("Error: no such option\r\n"); + return 0; + } + if(errno) { + printf("Error: %s\r\n", strerror(errno)); + return 0; + } + } + + buf = malloc(bufferSize); + if(buf == NULL) { + printf("Error: failed to allocate buffer\r\n"); + CloseHandle(inFile); + CloseHandle(outFile); + return 0; + } + h = CreateFile(target, desiredAccess, shareMode, NULL, disposition, flags, NULL); + if (h == INVALID_HANDLE_VALUE) { + printf("Error: CreateFile operation failed: %u\r\n", GetLastError()); + CloseHandle(inFile); + CloseHandle(outFile); + return 0; + } + if(inFile != NULL || outFile != NULL) { + /* need to do reading or writing of some sort on the pipe */ + + if(inFile == NULL) { + inFile = h; + } + if(outFile == NULL) { + outFile = h; + } + while(ReadFile(inFile, buf, bufferSize, &bytesRead, NULL) > 0) { + WriteFile(outFile, buf, bytesRead, &bytesRead, NULL); + } + } + printf("Success: operation performed successfully\r\n"); + CloseHandle(inFile); + CloseHandle(outFile); + CloseHandle(h); + return 1; +} + diff --git a/examples/pipes/createnp.c b/examples/pipes/createnp.c new file mode 100644 index 0000000..62314d0 --- /dev/null +++ b/examples/pipes/createnp.c @@ -0,0 +1,164 @@ +/* examples for the jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * 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. + */ + +/* createnp.c - Create a named pipe with CreateNamedPipe. + */ + +#include +#include +#include + +#define hexstrtoui(s) ((int)strtoul((s), NULL, 16)) + +int +main(int argc, char *argv[]) +{ + int i; + int openMode, pipeMode, bufferSize, defaultTimeout, bytesRead; + char *target, *buf; + HANDLE h, inFile, outFile; + + inFile = NULL; + outFile = NULL; + openMode = PIPE_ACCESS_DUPLEX; + pipeMode = PIPE_TYPE_BYTE | PIPE_WAIT; + bufferSize = 65535; + + if (argc == 1 || argv[1][1] == '\?') { + + /* dwOpenMode + */ + printf("dwOpenMode\r\n"); + printf(" 0x%08x PIPE_ACCESS_DUPLEX\r\n", PIPE_ACCESS_DUPLEX); + printf(" 0x%08x PIPE_ACCESS_INBOUND\r\n", PIPE_ACCESS_INBOUND); + printf(" 0x%08x PIPE_ACCESS_OUTBOUND\r\n", PIPE_ACCESS_OUTBOUND); + printf(" 0x%08x FILE_FLAG_WRITE_THROUGH\r\n", FILE_FLAG_WRITE_THROUGH); + printf(" 0x%08x FILE_FLAG_OVERLAPPED\r\n", FILE_FLAG_OVERLAPPED); + printf(" 0x%08x WRITE_DAC\r\n", WRITE_DAC); + printf(" 0x%08x WRITE_OWNER\r\n", WRITE_OWNER); + printf(" 0x%08x ACCESS_SYSTEM_SECURITY\r\n", ACCESS_SYSTEM_SECURITY); + /* dwPipeMode + */ + printf("dwPipeMode\r\n"); + printf(" 0x%08x PIPE_TYPE_BYTE\r\n", PIPE_TYPE_BYTE); + printf(" 0x%08x PIPE_TYPE_MESSAGE\r\n", PIPE_TYPE_MESSAGE); + printf(" 0x%08x PIPE_READMODE_BYTE\r\n", PIPE_READMODE_BYTE); + printf(" 0x%08x PIPE_READMODE_MESSAGE\r\n", PIPE_READMODE_MESSAGE); + printf(" 0x%08x PIPE_WAIT\r\n", PIPE_WAIT); + printf(" 0x%08x PIPE_NOWAIT\r\n", PIPE_NOWAIT); + + printf("defaults\r\n"); + printf(" inFile = \r\n"); + printf(" outFile = \r\n"); + printf(" dwOpenMode = PIPE_ACCESS_DUPLEX\r\n"); + printf(" dwPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT\r\n"); + printf(" bufferSize = 65535\r\n"); + + printf("\r\ncreatenp \\\\.\\pipe\\name /I inFile /O outFile /M mode /P pmode /B bufferSize\r\n"); + + return 0; + } + + if(argv[1][0] != '\\' && argv[1][1] != '\\') { + printf("Error: must specify target\r\n"); + } + target = argv[1]; + for(i = 2; i < argc; i++) { + if(argv[i][0] != '/') { + printf("Error: invalid switch\r\n"); + } + errno = 0; + switch(argv[i++][1]) { + case 'I': + inFile = CreateFile(argv[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(inFile == INVALID_HANDLE_VALUE) { + printf("Error: cannot open inFile: %s\r\n", argv[i]); + CloseHandle(outFile); + return 0; + } + break; + case 'O': + outFile = CreateFile(argv[i], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if(outFile == INVALID_HANDLE_VALUE) { + printf("Error: cannot open outFile: %s\r\n", argv[i]); + CloseHandle(inFile); + return 0; + } + break; + case 'M': + openMode = hexstrtoui(argv[i]); + break; + case 'P': + pipeMode = hexstrtoui(argv[i]); + break; + case 'B': + bufferSize = atoi(argv[i]); + break; + default: + printf("Error: no such option\r\n"); + CloseHandle(inFile); + CloseHandle(outFile); + return 0; + } + if(errno) { + printf("Error: values must be in hex.\r\n"); + CloseHandle(inFile); + CloseHandle(outFile); + return 0; + } + } + h = CreateNamedPipe(target, openMode, pipeMode, 1, bufferSize, bufferSize, NMPWAIT_WAIT_FOREVER, NULL); + if (h == INVALID_HANDLE_VALUE) { + printf("Error: CreateNamedPipe operation failed: %u\r\n", GetLastError()); + CloseHandle(inFile); + CloseHandle(outFile); + return 0; + } + if(ConnectNamedPipe(h, NULL) == 0 && GetLastError() != ERROR_PIPE_CONNECTED) { + printf("Error: ConnectNamedPipe operation failed: %u\r\n", GetLastError()); + CloseHandle(inFile); + CloseHandle(outFile); + CloseHandle(h); + return 0; + } + buf = malloc(bufferSize); + if(buf == NULL) { + printf("Error: failed to allocate buffer\r\n"); + CloseHandle(inFile); + CloseHandle(outFile); + DisconnectNamedPipe(h); + CloseHandle(h); + return 0; + } + if(inFile == NULL) { + inFile = h; + } + if(outFile == NULL) { + outFile = h; + } + while(ReadFile(inFile, buf, bufferSize, &bytesRead, NULL) > 0) { + WriteFile(outFile, buf, bytesRead, &bytesRead, NULL); + } + printf("Success: operation performed successfully\r\n"); + CloseHandle(inFile); + CloseHandle(outFile); + DisconnectNamedPipe(h); + CloseHandle(h); + return 1; +} + diff --git a/examples/run1.sh b/examples/run1.sh new file mode 100644 index 0000000..84c1d10 --- /dev/null +++ b/examples/run1.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +JAVA_HOME=/usr/local/java +CLASSPATH=../build:. +PROPERTIES=../../user10.prp +RUN="${JAVA_HOME}/bin/java -cp ${CLASSPATH} -Djcifs.properties=${PROPERTIES}" + +SERVER=dc1.w.net +SHARE=tmp +WRITE_DIR=test/ +SRC_DIR=test/Junk +FILE1=test/Junk/10883563.doc + +URL_SERVER=smb://${SERVER}/ +URL_SHARE=${URL_SERVER}${SHARE}/ +URL_WRITE_DIR=${URL_SHARE}${WRITE_DIR} + +[ "$1" = "ListACL" ] && $RUN ListACL ${URL_WRITE_DIR} +[ "$1" = "LargeListFiles" ] && $RUN LargeListFiles ${URL_WRITE_DIR} +[ "$1" = "CountPerms" ] && $RUN CountPerms ${URL_WRITE_DIR} 100 +[ "$1" = "AclCrawler" ] && $RUN AclCrawler ${URL_WRITE_DIR} 100 +[ "$1" = "SidCacheTest" ] && $RUN SidCacheTest ${URL_WRITE_DIR} +[ "$1" = "GetSecurity" ] && $RUN GetSecurity ${URL_WRITE_DIR} +[ "$1" = "GetSecurityS" ] && $RUN GetSecurity ${URL_SHARE} +[ "$1" = "GetShareSecurity" ] && $RUN GetShareSecurity ${URL_WRITE_DIR} +[ "$1" = "SidCrawler" ] && $RUN SidCrawler ${URL_WRITE_DIR} 5 +[ "$1" = "GetGroupMemberSidsFromURL" ] && $RUN GetGroupMemberSidsFromURL ${URL_WRITE_DIR} +[ "$1" = "InterruptTest" ] && $RUN InterruptTest ${URL_WRITE_DIR}Append.txt +[ "$1" = "AllocInfo" ] && $RUN AllocInfo ${URL_SHARE} +[ "$1" = "Append" ] && $RUN Append ${URL_WRITE_DIR}Append.txt +[ "$1" = "AuthListFiles" ] && $RUN AuthListFiles smb://bogus\@${SERVER}/${SHARE}/ +[ "$1" = "CopyTo" ] && $RUN CopyTo ${URL_SHARE}${SRC_DIR}/ ${URL_SHARE}${WRITE_DIR}CopyTo/ +[ "$1" = "CreateFile" ] && $RUN CreateFile ${URL_WRITE_DIR}CreateFile.txt +[ "$1" = "Delete" ] && $RUN Delete ${URL_WRITE_DIR}CreateFile.txt +[ "$1" = "Equals" ] && $RUN Equals ${URL_WRITE_DIR}CreateFile.txt ${URL_SHARE}${WRITE_DIR}../${WRITE_DIR}CreateFile.txt +[ "$1" = "Exists" ] && $RUN Exists ${URL_WRITE_DIR} +[ "$1" = "FileInfo" ] && $RUN FileInfo ${URL_SHARE}${FILE1} 0 +[ "$1" = "FileOps" ] && $RUN FileOps ${URL_WRITE_DIR} +[ "$1" = "FilterFiles" ] && $RUN FilterFiles ${URL_SHARE}${SRC_DIR}/ +[ "$1" = "GetDate" ] && $RUN GetDate ${URL_SHARE}${FILE1} +[ "$1" = "Get" ] && $RUN Get ${URL_SHARE}test/Makefile.txt +[ "$1" = "GetType" ] && $RUN GetType ${URL_SHARE} +[ "$1" = "GrowWrite" ] && $RUN GrowWrite ${URL_WRITE_DIR}GrowWrite.txt +[ "$1" = "GetURL" ] && $RUN GetURL ${URL_WRITE_DIR}Append.txt +[ "$1" = "HttpURL" ] && $RUN HttpURL ${URL_WRITE_DIR} ../Append.txt +[ "$1" = "Interleave" ] && $RUN Interleave ${URL_WRITE_DIR} 25 +[ "$1" = "IsDir" ] && $RUN IsDir ${URL_SHARE}${SRC_DIR}/ +[ "$1" = "Length" ] && $RUN Length ${URL_SHARE}${FILE1} +[ "$1" = "ListFiles" ] && $RUN ListFiles ${URL_WRITE_DIR} +[ "$1" = "ListShares" ] && $RUN ListFiles ${URL_SERVER} +[ "$1" = "List" ] && $RUN List ${URL_WRITE_DIR} +[ "$1" = "ListTypes" ] && $RUN ListTypes ${URL_WRITE_DIR} +[ "$1" = "Mkdir" ] && $RUN Mkdir ${URL_WRITE_DIR}Mkdir +[ "$1" = "NodeStatus" ] && $RUN NodeStatus ${SERVER} +[ "$1" = "Put" ] && $RUN Put ${URL_WRITE_DIR}Makefile +[ "$1" = "Query" ] && $RUN Query ${SERVER} +[ "$1" = "RenameTo" ] && $RUN RenameTo ${URL_WRITE_DIR}Makefile ${URL_WRITE_DIR}Makefile.txt +[ "$1" = "SetAttrs" ] && $RUN SetAttrs ${URL_WRITE_DIR}Makefile.txt FFFF +[ "$1" = "SetTime" ] && $RUN SetTime ${URL_WRITE_DIR}Makefile.txt +[ "$1" = "SlowWrite" ] && $RUN SlowWrite ${URL_WRITE_DIR}SlowWrite.txt +[ "$1" = "SlowRead" ] && $RUN SlowRead ${URL_WRITE_DIR}SlowWrite.txt +[ "$1" = "SmbCrawler" ] && $RUN SmbCrawler ${URL_WRITE_DIR} 1000 +[ "$1" = "T2Crawler" ] && $RUN T2Crawler ${URL_WRITE_DIR} 3 1000 +[ "$1" = "TestRandomAccess1" ] && $RUN TestRandomAccess ${URL_WRITE_DIR}TestRandomAccess.bin 1 +[ "$1" = "TestRandomAccess2" ] && $RUN TestRandomAccess ${URL_WRITE_DIR}TestRandomAccess.bin 2 0 +[ "$1" = "TestRandomAccess3" ] && $RUN TestRandomAccess ${URL_WRITE_DIR}TestRandomAccess.bin 3 1234 + + diff --git a/examples/runtests.sh b/examples/runtests.sh new file mode 100644 index 0000000..cee995c --- /dev/null +++ b/examples/runtests.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +JAVA_HOME=/usr/local/java5 +CLASSPATH=../build:. +PROPERTIES=../../user2.prp +RUN="${JAVA_HOME}/bin/java -cp ${CLASSPATH} -Djcifs.properties=${PROPERTIES}" + +SERVER=192.168.2.110 +#SERVER=dc1.w.net +SHARE=tmp +DIR=test + +# Domain-based DFS +#SERVER=192.168.2.110 +#SERVER=w.net +#SHARE=root2 +#DIR=test + +# smb://fs4.w.net/DFSStandaloneRoot/DFSStandaloneLink/test/ +# smb://dc1.w.net/root2/link2/test/ +# smb://dc1.w.net/tmp/test/ +# smb://dc3.x.net/tmp/test/ +# Stand-alone DFS +#SERVER=192.168.2.113 +#SERVER=fs1.w.net +#SHARE=DFSStandaloneRoot +#DIR=DFSStandaloneLink/test + +WRITE_DIR=${DIR}/ +SRC_DIR=${DIR}/Junk +FILE1=${DIR}/Junk/10883563.doc +URL_SERVER=smb://${SERVER}/ +URL_SHARE=${URL_SERVER}${SHARE}/ +URL_WRITE_DIR=${URL_SHARE}${WRITE_DIR} + +set -x + +$RUN ListACL ${URL_WRITE_DIR} +$RUN LargeListFiles ${URL_WRITE_DIR} +$RUN CountPerms ${URL_WRITE_DIR} 100 +$RUN AclCrawler ${URL_WRITE_DIR} 100 +$RUN SidCacheTest ${URL_WRITE_DIR} +$RUN GetSecurity ${URL_WRITE_DIR} +$RUN GetSecurity ${URL_SHARE} +$RUN GetShareSecurity ${URL_WRITE_DIR} +$RUN SidCrawler ${URL_WRITE_DIR} 5 +$RUN GetGroupMemberSidsFromURL ${URL_WRITE_DIR} +$RUN InterruptTest ${URL_SHARE}${FILE1} +$RUN AllocInfo ${URL_SHARE} +$RUN Append ${URL_WRITE_DIR}Append.txt +$RUN AuthListFiles smb://bogus\@${SERVER}/${SHARE}/ +$RUN CopyTo ${URL_SHARE}${SRC_DIR}/ ${URL_SHARE}${WRITE_DIR}CopyTo/ +$RUN CreateFile ${URL_WRITE_DIR}CreateFile.txt +$RUN Delete ${URL_WRITE_DIR}CreateFile.txt +$RUN Equals ${URL_WRITE_DIR}CreateFile.txt ${URL_SHARE}${WRITE_DIR}../${WRITE_DIR}CreateFile.txt +$RUN Exists ${URL_WRITE_DIR} +$RUN FileInfo ${URL_SHARE}${FILE1} 0 +$RUN FileOps ${URL_WRITE_DIR} +$RUN FilterFiles ${URL_SHARE}${SRC_DIR}/ +$RUN GetDate ${URL_SHARE}${FILE1} +$RUN Get ${URL_SHARE}${FILE1} +$RUN GetType ${URL_SHARE} +$RUN GrowWrite ${URL_WRITE_DIR}GrowWrite.txt +$RUN GetURL ${URL_WRITE_DIR}Append.txt +$RUN HttpURL ${URL_WRITE_DIR} ../Append.txt +$RUN Interleave ${URL_WRITE_DIR} 3 +$RUN IsDir ${URL_SHARE}${SRC_DIR}/ +$RUN Length ${URL_SHARE}${FILE1} +$RUN ListFiles ${URL_WRITE_DIR} +$RUN ListFiles ${URL_SERVER} +$RUN List ${URL_WRITE_DIR} +$RUN ListTypes ${URL_WRITE_DIR} +$RUN Mkdir ${URL_WRITE_DIR}Mkdir +$RUN NodeStatus ${SERVER} +$RUN Put ${URL_WRITE_DIR}Makefile +$RUN Query ${SERVER} +$RUN RenameTo ${URL_WRITE_DIR}Makefile ${URL_WRITE_DIR}Makefile.txt +$RUN SetAttrs ${URL_WRITE_DIR}Makefile.txt FFFF +$RUN SetTime ${URL_WRITE_DIR}Makefile.txt +$RUN SlowWrite ${URL_WRITE_DIR}SlowWrite.txt +$RUN SlowRead ${URL_WRITE_DIR}SlowWrite.txt +$RUN SmbCrawler ${URL_WRITE_DIR} 1000 +$RUN T2Crawler ${URL_WRITE_DIR} 3 1000 +$RUN TestRandomAccess ${URL_WRITE_DIR}TestRandomAccess.bin 1 +$RUN TestRandomAccess ${URL_WRITE_DIR}TestRandomAccess.bin 2 0 +$RUN TestRandomAccess ${URL_WRITE_DIR}TestRandomAccess.bin 3 1234 + + diff --git a/examples/torture.prp b/examples/torture.prp new file mode 100644 index 0000000..1734acd --- /dev/null +++ b/examples/torture.prp @@ -0,0 +1,9 @@ + +torture.src.url = smb://dom\;miallen:pass@server/pub/ +torture.dst.domain = dom +torture.dst.username = miallen +torture.dst.password = pass +torture.dst.server = server/ +torture.dst.share = share52/ +torture.dst.directory = torture1/ + diff --git a/examples/torture2.prp b/examples/torture2.prp new file mode 100644 index 0000000..91ba1e0 --- /dev/null +++ b/examples/torture2.prp @@ -0,0 +1,7 @@ + +thread.0.from.url = smb://dom\;usr:pas@svr1/shr/dir/ +thread.0.to.url = smb://dom\;usr:pas@svr2/shr/dir/ +thread.1.from.url = smb://dom\;usr:pas@svr1/shr/dir/ +thread.1.to.url = smb://dom\;usr:pas@svr2/shr/dir/ +thread.2.from.url = smb://dom\;usr:pas@svr1/shr/dir/ +thread.2.to.url = smb://dom\;usr:pas@svr2/shr/dir/ diff --git a/examples/web.xml b/examples/web.xml new file mode 100644 index 0000000..3e4d30c --- /dev/null +++ b/examples/web.xml @@ -0,0 +1,35 @@ + + + + + + jcifs.netbios.wins + 164.152.78.10,164.152.4.22 + + + + jcifs.smb.client.domain + NYC-USERS + + + + jcifs.smb.client.username + jcifssvcacct + + + jcifs.smb.client.password + VeRYr@nDoMpa$sW0rD + + + + jcifs.util.loglevel + 2 + + + + + diff --git a/patches/DnsSrv.patch b/patches/DnsSrv.patch new file mode 100644 index 0000000..78a65d7 --- /dev/null +++ b/patches/DnsSrv.patch @@ -0,0 +1,102 @@ +diff -Naur old-src/jcifs/smb/SmbSession.java src/jcifs/smb/SmbSession.java +--- old-src/jcifs/smb/SmbSession.java 2006-11-29 12:12:52.000000000 -0500 ++++ src/jcifs/smb/SmbSession.java 2006-12-01 06:52:28.498008700 -0500 +@@ -18,6 +18,8 @@ + + package jcifs.smb; + ++import java.util.ArrayList; ++import java.util.List; + import java.util.Vector; + import java.util.Enumeration; + import java.net.InetAddress; +@@ -26,6 +28,11 @@ + import jcifs.UniAddress; + import jcifs.netbios.NbtAddress; + ++import javax.naming.NamingException; ++ ++import javax.naming.directory.Attributes; ++import javax.naming.directory.DirContext; ++import javax.naming.directory.InitialDirContext; + /** + * The class represents a user's session established with an SMB/CIFS + * server. This class is used internally to the jCIFS library however +@@ -63,12 +70,11 @@ + private static final int CACHE_POLICY = + Config.getInt( "jcifs.netbios.cachePolicy", 60 * 10 ) * 60; /* 10 hours */ + +- static NbtAddress[] dc_list = null; ++ static UniAddress[] dc_list = null; + static long dc_list_expiration; + static int dc_list_counter; + +- private static NtlmChallenge interrogate( NbtAddress addr ) throws SmbException { +- UniAddress dc = new UniAddress( addr ); ++ private static NtlmChallenge interrogate( UniAddress dc ) throws SmbException { + SmbTransport trans = SmbTransport.getSmbTransport( dc, 0 ); + if (USERNAME == null) { + trans.connect(); +@@ -95,13 +101,59 @@ + do { + if (dc_list_expiration < now) { + dc_list_expiration = now + CACHE_POLICY * 1000L; +- NbtAddress[] list = NbtAddress.getAllByName( DOMAIN, 0x1C, null, null ); +- if (list != null && list.length > 0) { ++ UniAddress[] list = null; ++ if (NbtAddress.getWINSAddress() != null) { ++ NbtAddress[] nbt_list = NbtAddress.getAllByName( DOMAIN, ++ 0x1C, null, null ); ++ if (nbt_list != null && nbt_list.length > 0) { ++ list = new UniAddress[nbt_list.length]; ++ for (int i = 0; i < list.length; i++) { ++ list[i] = new UniAddress(nbt_list[i]); ++ } ++ } ++ } else { ++ try { ++ DirContext context = new InitialDirContext(); ++ Attributes attributes = context.getAttributes( ++ "dns:/_ldap._tcp.dc._msdcs." + DOMAIN, ++ new String[] { "SRV" }); ++ Enumeration values = attributes.get("SRV").getAll(); ++ List results = new ArrayList(); ++ while (values.hasMoreElements()) { ++ String value = (String) values.nextElement(); ++ value = value.replaceFirst( ++ "^\\d* \\d* \\d+ (.*)\\.$", "$1"); ++ try { ++ InetAddress server = ++ InetAddress.getByName(value); ++ results.add(new UniAddress(server)); ++ } catch (UnknownHostException ex) { ++ if (SmbTransport.log.level >= 2) { ++ SmbTransport.log.println( ++ "Unable to resolve DC SRV entry: " + ++ value); ++ if (SmbTransport.log.level > 2) { ++ ex.printStackTrace(SmbTransport.log); ++ } ++ } ++ } ++ } ++ if (!results.isEmpty()) { ++ list = (UniAddress[]) ++ results.toArray(new UniAddress[0]); ++ } ++ } catch (NamingException ne) { ++ if (SmbTransport.log.level > 2) { ++ ne.printStackTrace(SmbTransport.log); ++ } ++ } ++ } ++ if (list != null) { + dc_list = list; + } else { /* keep using the old list */ + dc_list_expiration = now + 1000 * 60 * 15; /* 15 min */ + if (SmbTransport.log.level >= 2) { +- SmbTransport.log.println( "Failed to retrieve DC list from WINS" ); ++ SmbTransport.log.println( "Failed to retrieve DC list" ); + } + } + } diff --git a/patches/Eventlog.patch b/patches/Eventlog.patch new file mode 100644 index 0000000..dce31a5 --- /dev/null +++ b/patches/Eventlog.patch @@ -0,0 +1,834 @@ +diff -Naur old-src/jcifs/dcerpc/DcerpcBinding.java src/jcifs/dcerpc/DcerpcBinding.java +--- old-src/jcifs/dcerpc/DcerpcBinding.java 2007-01-22 17:21:18.000000000 -0800 ++++ src/jcifs/dcerpc/DcerpcBinding.java 2007-03-20 10:33:47.000000000 -0700 +@@ -32,6 +32,7 @@ + INTERFACES = new HashMap(); + INTERFACES.put("srvsvc", srvsvc.getSyntax()); + INTERFACES.put("lsarpc", lsarpc.getSyntax()); ++ INTERFACES.put("eventlog", eventlog.getSyntax()); + } + + String proto; +diff -Naur old-src/jcifs/dcerpc/msrpc/eventlog.idl src/jcifs/dcerpc/msrpc/eventlog.idl +--- old-src/jcifs/dcerpc/msrpc/eventlog.idl 1969-12-31 16:00:00.000000000 -0800 ++++ src/jcifs/dcerpc/msrpc/eventlog.idl 2007-03-20 10:33:47.000000000 -0700 +@@ -0,0 +1,148 @@ ++[ ++ uuid("82273fdc-e32a-18c3-3f78-827929dc23ea"), ++ version(0.0), ++] ++interface eventlog ++{ ++ typedef bitmap { ++ EVENTLOG_SEQUENTIAL_READ = 0x0001, ++ EVENTLOG_SEEK_READ = 0x0002, ++ EVENTLOG_FORWARDS_READ = 0x0004, ++ EVENTLOG_BACKWARDS_READ = 0x0008 ++ } EventlogReadFlags; ++ ++ typedef bitmap { ++ EVENTLOG_SUCCESS = 0x0000, ++ EVENTLOG_ERROR_TYPE = 0x0001, ++ EVENTLOG_WARNING_TYPE = 0x0002, ++ EVENTLOG_INFORMATION_TYPE = 0x0004, ++ EVENTLOG_AUDIT_SUCCESS = 0x0008, ++ EVENTLOG_AUDIT_FAILURE = 0x0010 ++ } EventlogEventTypes; ++ ++ typedef struct { ++ uint16 unknown0; ++ uint16 unknown1; ++ } EventlogOpenUnknown0; ++ ++ typedef [public] struct { ++ uint32 size; ++ uint32 reserved; ++ uint32 record_number; ++ uint32 time_generated; ++ uint32 time_written; ++ uint32 event_id; ++ uint16 event_type; ++ uint16 num_of_strings; ++ uint16 event_category; ++ uint16 reserved_flags; ++ uint32 closing_record_number; ++ uint32 stringoffset; ++ uint32 sid_length; ++ uint32 sid_offset; ++ uint32 data_length; ++ uint32 data_offset; ++ nstring source_name; ++ nstring computer_name; ++ nstring strings[num_of_strings]; ++ astring raw_data; ++ } EventlogRecord; ++ ++ [op(0x00)] ++ NTSTATUS eventlog_ClearEventLogW( ++ [in] policy_handle *handle, ++ [in,unique] lsa_String *unknown ++ ); ++ ++ [op(0x01)] ++ NTSTATUS eventlog_BackupEventLogW(); ++ ++ [op(0x02)] ++ NTSTATUS eventlog_CloseEventLog( ++ [in,out] policy_handle *handle ++ ); ++ ++ [op(0x03)] ++ NTSTATUS eventlog_DeregisterEventSource(); ++ ++ [op(0x04)] ++ NTSTATUS eventlog_GetNumRecords( ++ [in] policy_handle *handle, ++ [out] uint32 *number ++ ); ++ ++ [op(0x05)] ++ NTSTATUS eventlog_GetOldestRecord(); ++ ++ [op(0x06)] ++ NTSTATUS eventlog_ChangeNotify(); ++ ++ [op(0x07)] ++ NTSTATUS eventlog_OpenEventLogW( ++ [in,unique] eventlog_OpenUnknown0 *unknown0, ++ [in] lsa_String logname, ++ [in] lsa_String servername, ++ [in] uint32 unknown2, ++ [in] uint32 unknown3, ++ [out] policy_handle *handle ++ ); ++ ++ [op(0x08)] ++ NTSTATUS eventlog_RegisterEventSourceW(); ++ ++ [op(0x09)] ++ NTSTATUS eventlog_OpenBackupEventLogW(); ++ ++ [op(0x0a)] ++ NTSTATUS eventlog_ReadEventLogW( ++ [in] policy_handle *handle, ++ [in] uint32 flags, ++ [in] uint32 offset, ++ [in] uint32 number_of_bytes, ++ [out,size_is(number_of_bytes)] uint8 *data, ++ [out] uint32 *sent_size, ++ [out] uint32 *real_size ++ ); ++ ++ [op(0x0b)] ++ NTSTATUS eventlog_ReportEventW(); ++ ++ [op(0x0c)] ++ NTSTATUS eventlog_ClearEventLogA(); ++ ++ [op(0x0d)] ++ NTSTATUS eventlog_BackupEventLogA(); ++ ++ [op(0x0e)] ++ NTSTATUS eventlog_OpenEventLogA(); ++ ++ [op(0x0f)] ++ NTSTATUS eventlog_RegisterEventSourceA(); ++ ++ [op(0x10)] ++ NTSTATUS eventlog_OpenBackupEventLogA(); ++ ++ [op(0x11)] ++ NTSTATUS eventlog_ReadEventLogA(); ++ ++ [op(0x12)] ++ NTSTATUS eventlog_ReportEventA(); ++ ++ [op(0x13)] ++ NTSTATUS eventlog_RegisterClusterSvc(); ++ ++ [op(0x14)] ++ NTSTATUS eventlog_DeregisterClusterSvc(); ++ ++ [op(0x15)] ++ NTSTATUS eventlog_WriteClusterEvents(); ++ ++ [op(0x16)] ++ NTSTATUS eventlog_GetLogIntormation(); ++ ++ [op(0x17)] ++ NTSTATUS eventlog_FlushEventLog( ++ [in] policy_handle *handle ++ ); ++} ++ +diff -Naur old-src/jcifs/dcerpc/msrpc/eventlog.java src/jcifs/dcerpc/msrpc/eventlog.java +--- old-src/jcifs/dcerpc/msrpc/eventlog.java 1969-12-31 16:00:00.000000000 -0800 ++++ src/jcifs/dcerpc/msrpc/eventlog.java 2007-03-20 10:33:47.000000000 -0700 +@@ -0,0 +1,464 @@ ++package jcifs.dcerpc.msrpc; ++ ++import java.util.ArrayList; ++import java.util.Date; ++import java.util.List; ++ ++import jcifs.dcerpc.DcerpcMessage; ++import jcifs.dcerpc.rpc; ++import jcifs.dcerpc.ndr.NdrBuffer; ++import jcifs.dcerpc.ndr.NdrException; ++import jcifs.dcerpc.ndr.NdrObject; ++ ++public class eventlog { ++ ++ public static String getSyntax() { ++ return "82273fdc-e32a-18c3-3f78-827929dc23ea:0.0"; ++ } ++ ++ public static final int EVENTLOG_SEQUENTIAL_READ = 0x0001; ++ ++ public static final int EVENTLOG_SEEK_READ = 0x0002; ++ ++ public static final int EVENTLOG_FORWARDS_READ = 0x0004; ++ ++ public static final int EVENTLOG_BACKWARDS_READ = 0x0008; ++ ++ public static final int EVENTLOG_SUCCESS = 0x0000; ++ ++ public static final int EVENTLOG_ERROR_TYPE = 0x0001; ++ ++ public static final int EVENTLOG_WARNING_TYPE = 0x0002; ++ ++ public static final int EVENTLOG_INFORMATION_TYPE = 0x0004; ++ ++ public static final int EVENTLOG_AUDIT_SUCCESS = 0x0008; ++ ++ public static final int EVENTLOG_AUDIT_FAILURE = 0x0010; ++ ++ public static class EventlogOpenUnknown0 extends NdrObject { ++ ++ public short unknown0; ++ ++ public short unknown1; ++ ++ public void encode(NdrBuffer _dst) throws NdrException { ++ _dst.align(4); ++ _dst.enc_ndr_short(unknown0); ++ _dst.enc_ndr_short(unknown1); ++ } ++ ++ public void decode(NdrBuffer _src) throws NdrException { ++ _src.align(4); ++ unknown0 = (short) _src.dec_ndr_short(); ++ unknown1 = (short) _src.dec_ndr_short(); ++ } ++ } ++ ++ public static class sid_t extends NdrObject { ++ ++ public byte revision; ++ ++ public byte[] identifier_authority; ++ ++ public int[] sub_authority; ++ ++ public void encode(NdrBuffer _dst) throws NdrException { ++ _dst.enc_ndr_small(revision); ++ _dst.enc_ndr_small(sub_authority.length); ++ for (int i = 0; i < 6; i++) { ++ _dst.enc_ndr_small(identifier_authority[i]); ++ } ++ for (int i = 0; i < sub_authority.length; i++) { ++ _dst.enc_ndr_long_noalign(sub_authority[i]); ++ } ++ } ++ ++ public void decode(NdrBuffer _src) throws NdrException { ++ revision = (byte) _src.dec_ndr_small(); ++ int sub_authority_count = (byte) _src.dec_ndr_small(); ++ ++ identifier_authority = new byte[6]; ++ for (int i = 0; i < 6; i++) { ++ identifier_authority[i] = (byte) _src.dec_ndr_small(); ++ } ++ sub_authority = new int[sub_authority_count]; ++ for (int i = 0; i < sub_authority_count; i++) { ++ sub_authority[i] = (int) _src.dec_ndr_long_noalign(); ++ } ++ } ++ ++ public String toString() { ++ StringBuffer sb = new StringBuffer(); ++ long ia; ++ ia = (identifier_authority[5]) + (identifier_authority[4] << 8) ++ + (identifier_authority[3] << 16) ++ + (identifier_authority[2] << 24); ++ sb.append("S-").append(revision).append("-").append(ia); ++ for (int i = 0; i < sub_authority.length; i++) { ++ sb.append("-").append(sub_authority[i]); ++ } ++ return sb.toString(); ++ } ++ } ++ ++ public static class EventlogRecord extends NdrObject { ++ public int size; ++ ++ public int reserved; ++ ++ public int record_number; ++ ++ public Date time_generated; ++ ++ public Date time_written; ++ ++ public int event_id; ++ ++ public short event_type; ++ ++ public short event_category; ++ ++ public short reserved_flags; ++ ++ public int closing_record_number; ++ ++ public eventlog.sid_t sid; ++ ++ public String source_name; ++ ++ public String computer_name; ++ ++ public String[] strings; ++ ++ public byte[] raw_data; ++ ++ public void encode(NdrBuffer _dst) throws NdrException { ++ int size = 0, size_offset = 0, size_offset2 = 0; ++ int stringoffset = 0, stringoffset_offset = 0; ++ int sid_length = 0, sid_length_offset = 0; ++ int sid_offset = 0, sid_offset_offset = 0; ++ int data_offset = 0, data_offset_offset = 0; ++ size_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(size); ++ _dst.enc_ndr_long(reserved); ++ _dst.enc_ndr_long(record_number); ++ _dst.enc_ndr_long(time_generated == null ? 0 ++ : (int) (time_generated.getTime() / 1000)); ++ _dst.enc_ndr_long(time_written == null ? 0 : (int) (time_written ++ .getTime() / 1000)); ++ _dst.enc_ndr_long(event_id); ++ _dst.enc_ndr_short(event_type); ++ _dst.enc_ndr_short(strings == null ? 0 : strings.length); ++ _dst.enc_ndr_short(event_category); ++ _dst.enc_ndr_short(reserved_flags); ++ _dst.enc_ndr_long(closing_record_number); ++ stringoffset_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(stringoffset); ++ sid_length_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(sid_length); ++ sid_offset_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(sid_offset); ++ _dst.enc_ndr_long(raw_data == null ? 0 : raw_data.length); ++ data_offset_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(data_offset); ++ _dst.enc_ndr_string(source_name); ++ _dst.enc_ndr_string(computer_name); ++ sid_offset = _dst.getIndex(); ++ if (sid != null) { ++ sid.encode(_dst); ++ sid_length = _dst.getIndex() - sid_offset; ++ } ++ stringoffset = _dst.getIndex(); ++ if (strings != null && strings.length > 0) { ++ for (int i = 0; i < strings.length; i++) { ++ _dst.enc_ndr_string(strings[i]); ++ } ++ } ++ data_offset = _dst.getIndex(); ++ if (raw_data != null && raw_data.length > 0) { ++ _dst.writeOctetArray(raw_data, 0, raw_data.length); ++ } ++ size_offset2 = _dst.getIndex(); ++ _dst.enc_ndr_long(size); ++ size = _dst.getIndex() - size_offset; ++ // Write information back. ++ _dst.setIndex(size_offset); ++ _dst.enc_ndr_long(size); ++ _dst.setIndex(stringoffset_offset); ++ _dst.enc_ndr_long(stringoffset); ++ _dst.setIndex(sid_length_offset); ++ _dst.enc_ndr_long(sid_length); ++ _dst.setIndex(sid_offset_offset); ++ _dst.enc_ndr_long(sid_offset); ++ _dst.setIndex(data_offset_offset); ++ _dst.enc_ndr_long(data_offset); ++ _dst.setIndex(size_offset2); ++ _dst.enc_ndr_long(size); ++ } ++ ++ public void decode(NdrBuffer _src) throws NdrException { ++ int cur_offset = _src.getIndex(); ++ size = _src.dec_ndr_long(); ++ reserved = _src.dec_ndr_long(); ++ record_number = _src.dec_ndr_long(); ++ long tmp = 0; ++ tmp = _src.dec_ndr_long(); ++ time_generated = new Date(tmp * 1000); ++ tmp = _src.dec_ndr_long(); ++ time_written = new Date(tmp * 1000); ++ event_id = _src.dec_ndr_long(); ++ event_type = (short) _src.dec_ndr_short(); ++ int num_of_strings = _src.dec_ndr_short(); ++ event_category = (short) _src.dec_ndr_short(); ++ reserved_flags = (short) _src.dec_ndr_short(); ++ closing_record_number = _src.dec_ndr_long(); ++ int stringoffset = _src.dec_ndr_long(); ++ int sid_length = _src.dec_ndr_long(); ++ int sid_offset = _src.dec_ndr_long(); ++ int data_length = _src.dec_ndr_long(); ++ int data_offset = _src.dec_ndr_long(); ++ source_name = _src.dec_ndr_unistring(); ++ computer_name = _src.dec_ndr_unistring(); ++ if (sid_length > 0) { ++ _src.setIndex(cur_offset + sid_offset); ++ if (sid == null) { ++ sid = new eventlog.sid_t(); ++ } ++ sid.decode(_src); ++ } else { ++ sid = null; ++ } ++ if (num_of_strings > 0) { ++ _src.setIndex(cur_offset + stringoffset); ++ strings = new String[num_of_strings]; ++ for (int i = 0; i < strings.length; i++) { ++ strings[i] = _src.dec_ndr_unistring(); ++ } ++ } else { ++ strings = new String[0]; ++ } ++ if (data_length > 0) { ++ _src.setIndex(cur_offset + data_offset); ++ raw_data = new byte[data_length]; ++ _src.readOctetArray(raw_data, 0, data_length); ++ } else { ++ raw_data = new byte[0]; ++ } ++ _src.setIndex(cur_offset + size); ++ } ++ } ++ ++ public static class EventlogClearEventLog extends DcerpcMessage { ++ ++ public int getOpnum() { ++ return 0x00; ++ } ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public rpc.unicode_string backupFile; ++ ++ public EventlogClearEventLog(rpc.policy_handle handle, ++ rpc.unicode_string backupfile) { ++ this.handle = handle; ++ this.backupFile = backupfile; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ handle.encode(_dst); ++ backupFile.encode(_dst); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ retval = (int) _src.dec_ndr_long(); ++ } ++ } ++ ++ public static class EventLogCloseEventLog extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x02; ++ } ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogCloseEventLog(rpc.policy_handle handle) { ++ this.handle = handle; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ handle.encode(_dst); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ handle.decode(_src); ++ retval = (int) _src.dec_ndr_long(); ++ } ++ } ++ ++ public static class EventLogGetNumRecords extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x04; ++ } ++ ++ public int numberOfRecords; ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogGetNumRecords(rpc.policy_handle handle) { ++ this.handle = handle; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ handle.encode(_dst); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ numberOfRecords = (int) _src.dec_ndr_long(); ++ retval = (int) _src.dec_ndr_long(); ++ } ++ } ++ ++ public static class EventLogGetOldestEntry extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x05; ++ } ++ ++ public int oldestEntryNumber; ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogGetOldestEntry(rpc.policy_handle handle) { ++ this.handle = handle; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ handle.encode(_dst); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ oldestEntryNumber = (int) _src.dec_ndr_long(); ++ retval = (int) _src.dec_ndr_long(); ++ } ++ } ++ ++ public static class EventLogOpenEventLog extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x07; ++ } ++ ++ public rpc.unicode_string logname; ++ ++ public rpc.unicode_string servername; ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogOpenEventLog(rpc.unicode_string logname, ++ rpc.unicode_string servername) { ++ this.logname = logname; ++ this.servername = servername; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ _dst.align(8); ++ _dst.enc_ndr_long(0xf000baaa); ++ _dst.enc_ndr_short(0x64); ++ _dst.enc_ndr_short(0x01); ++ logname.encode(_dst); ++ servername.encode(_dst); ++ // _dst.align(4); ++ _dst.enc_ndr_long(0x01); ++ _dst.enc_ndr_long(0x01); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ if (handle == null) { ++ handle = new rpc.policy_handle(); ++ } ++ handle.decode(_src); ++ retval = (int) _src.dec_ndr_long(); ++ } ++ } ++ ++ public static class EventLogReadEventLog extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x0a; ++ } ++ ++ public int retval; ++ ++ public int flags; ++ ++ public int offset; ++ ++ public int maxReadSize; ++ ++ public int bytesInNextRecords; ++ ++ public List entries; ++ ++ public int sent_size; ++ ++ public int real_size; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogReadEventLog(rpc.policy_handle handle, int flags, ++ int offset, int maxReadSize) { ++ this.handle = handle; ++ this.flags = flags; ++ this.offset = offset; ++ this.maxReadSize = maxReadSize; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ _dst.align(8); ++ handle.encode(_dst); ++ _dst.enc_ndr_long(flags); ++ _dst.enc_ndr_long(offset); ++ _dst.enc_ndr_long(maxReadSize); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ int bytesInResponse = 0, curOffset = 0, bytesTotal = 0; ++ bytesInResponse = _src.dec_ndr_long(); ++ curOffset = _src.getIndex(); ++ _src.setIndex(curOffset + bytesInResponse); ++ sent_size = _src.dec_ndr_long(); ++ real_size = _src.dec_ndr_long(); ++ retval = (int) _src.dec_ndr_long(); ++ _src.setIndex(curOffset); ++ while (bytesTotal < sent_size) { ++ if (entries == null) { ++ entries = new ArrayList(); ++ } ++ EventlogRecord entry = new EventlogRecord(); ++ entry.decode(_src); ++ entries.add(entry); ++ bytesTotal += entry.size; ++ } ++ } ++ } ++} ++ +diff -Naur old-src/jcifs/dcerpc/ndr/NdrBuffer.java src/jcifs/dcerpc/ndr/NdrBuffer.java +--- old-src/jcifs/dcerpc/ndr/NdrBuffer.java 2007-01-22 17:21:18.000000000 -0800 ++++ src/jcifs/dcerpc/ndr/NdrBuffer.java 2007-03-20 10:41:37.000000000 -0700 +@@ -120,33 +120,51 @@ + } + public void enc_ndr_short(int s) { + align(2); ++ enc_ndr_small_noalign(s); ++ } ++ public void enc_ndr_small_noalign(int s) { + Encdec.enc_uint16le((short)s, buf, index); + advance(2); + } + public int dec_ndr_short() { + align(2); ++ return dec_ndr_short_noalign(); ++ } ++ public int dec_ndr_short_noalign() { + int val = Encdec.dec_uint16le(buf, index); + advance(2); + return val; + } + public void enc_ndr_long(int l) { + align(4); ++ enc_ndr_long_noalign(l); ++ } ++ public void enc_ndr_long_noalign(int l) { + Encdec.enc_uint32le(l, buf, index); + advance(4); + } + public int dec_ndr_long() { + align(4); ++ return dec_ndr_long_noalign(); ++ } ++ public int dec_ndr_long_noalign() { + int val = Encdec.dec_uint32le(buf, index); + advance(4); + return val; + } + public void enc_ndr_hyper(long h) { + align(8); ++ enc_ndr_hyper_noalign(h); ++ } ++ public void enc_ndr_hyper_noalign(long h) { + Encdec.enc_uint64le(h, buf, index); + advance(8); + } + public long dec_ndr_hyper() { + align(8); ++ return dec_ndr_hyper_noalign(); ++ } ++ public long dec_ndr_hyper_noalign() { + long val = Encdec.dec_uint64le(buf, index); + advance(8); + return val; +@@ -155,6 +173,9 @@ + /* double */ + public void enc_ndr_string(String s) { + align(4); ++ enc_ndr_string_noalign(s); ++ } ++ public void enc_ndr_string_noalign(String s) { + int i = index; + int len = s.length(); + Encdec.enc_uint32le(len + 1, buf, i); i += 4; +@@ -171,6 +192,9 @@ + } + public String dec_ndr_string() throws NdrException { + align(4); ++ return dec_ndr_string_noalign(); ++ } ++ public String dec_ndr_string_noalign() throws NdrException { + int i = index; + String val = null; + int len = Encdec.dec_uint32le(buf, i); +@@ -188,6 +212,67 @@ + advance(i - index); + return val; + } ++ ++ /** ++ * Encode a string into unicode format. It's not UNISTR2 format, doesn't ++ * include length and so on. Just string in UnicodeLittleUnmarked format. ++ * Been used by eventlog APIs. ++ * ++ * @param s ++ * The string that need to encode. ++ */ ++ public void enc_ndr_unistring(String s) { ++ align(2); ++ enc_ndr_unistring_noalign(s); ++ } ++ public void enc_ndr_unistring_noalign(String s) { ++ int i = index; ++ int len = s.length(); ++ try { ++ System.arraycopy(s.getBytes("UnicodeLittleUnmarked"), 0, buf, i, ++ len * 2); ++ } catch (UnsupportedEncodingException uee) { ++ } ++ i += len * 2; ++ buf[i++] = (byte) '\0'; ++ buf[i++] = (byte) '\0'; ++ advance(i - index); ++ } ++ ++ /** ++ * Decode a unicode string. It's not UNISTR2 format, doesn't include length ++ * and so on. Just string in UnicodeLittleUnmarked format. Been used by ++ * eventlog APIs. ++ * ++ * @return decoded java string object. ++ */ ++ public String dec_ndr_unistring() throws NdrException { ++ align(2); ++ return dec_ndr_unistring_noalign(); ++ } ++ public String dec_ndr_unistring_noalign() throws NdrException { ++ int i = index; ++ String val = null; ++ int tmp; ++ int len = 0; ++ do { ++ tmp = dec_ndr_short(); ++ len++; ++ } while (tmp != 0); ++ if (len != 0) { ++ len--; ++ int size = len * 2; ++ try { ++ if (size < 0 || size > 0xFFFF) ++ throw new NdrException(NdrException.INVALID_CONFORMANCE); ++ val = new String(buf, i, size, "UnicodeLittleUnmarked"); ++ i += size + 2; ++ } catch (UnsupportedEncodingException uee) { ++ } ++ } ++ advance(i - index); ++ return val; ++ } + private int getDceReferent(Object obj) { + Entry e; + +diff -Naur old-src/jcifs/dcerpc/UnicodeString.java src/jcifs/dcerpc/UnicodeString.java +--- old-src/jcifs/dcerpc/UnicodeString.java 2007-01-22 17:21:18.000000000 -0800 ++++ src/jcifs/dcerpc/UnicodeString.java 2007-03-20 10:33:47.000000000 -0700 +@@ -27,20 +27,24 @@ + this.zterm = zterm; + } + public UnicodeString(rpc.unicode_string rus, boolean zterm) { +- this.length = rus.length; +- this.maximum_length = rus.maximum_length; +- this.buffer = rus.buffer; ++ this.length = rus == null ? 0 : rus.length; ++ this.maximum_length = rus == null ? 0 : rus.maximum_length; ++ this.buffer = rus == null ? null : rus.buffer; + this.zterm = zterm; + } + + public UnicodeString(String str, boolean zterm) { + this.zterm = zterm; + +- int len = str.length(); ++ int len = str == null ? 0 : str.length(); + int zt = zterm ? 1 : 0; + + length = maximum_length = (short)((len + zt) * 2); +- buffer = new short[len + zt]; ++ if (str != null) { ++ buffer = new short[len + zt]; ++ } else { ++ buffer = null; ++ } + + int i; + for (i = 0; i < len; i++) { +diff -Naur old-src/jcifs/smb/NtStatus.java src/jcifs/smb/NtStatus.java +--- old-src/jcifs/smb/NtStatus.java 2007-01-22 17:21:18.000000000 -0800 ++++ src/jcifs/smb/NtStatus.java 2007-03-20 10:33:47.000000000 -0700 +@@ -33,6 +33,7 @@ + public static final int NT_STATUS_INVALID_PARAMETER = 0xC000000d; + public static final int NT_STATUS_NO_SUCH_DEVICE = 0xC000000e; + public static final int NT_STATUS_NO_SUCH_FILE = 0xC000000f; ++ public static final int NT_STATUS_END_OF_FILE = 0xC0000011; + public static final int NT_STATUS_ACCESS_DENIED = 0xC0000022; + public static final int NT_STATUS_BUFFER_TOO_SMALL = 0xC0000023; + public static final int NT_STATUS_OBJECT_NAME_INVALID = 0xC0000033; +@@ -87,6 +88,7 @@ + NT_STATUS_INVALID_PARAMETER, + NT_STATUS_NO_SUCH_DEVICE, + NT_STATUS_NO_SUCH_FILE, ++ NT_STATUS_END_OF_FILE, + NT_STATUS_ACCESS_DENIED, + NT_STATUS_BUFFER_TOO_SMALL, + NT_STATUS_OBJECT_NAME_INVALID, +@@ -142,6 +144,7 @@ + "The parameter is incorrect.", + "The system cannot find the file specified.", + "The system cannot find the file specified.", ++ "Reached end of file.", + "Access is denied.", + "The data area passed to a system call is too small.", + "The filename, directory name, or volume label syntax is incorrect.", diff --git a/patches/GetOwnerSid.patch b/patches/GetOwnerSid.patch new file mode 100644 index 0000000..7af5d06 --- /dev/null +++ b/patches/GetOwnerSid.patch @@ -0,0 +1,91 @@ +diff -r temp/jcifs_1.2.13/src/jcifs/smb/SecurityDescriptor.java workspace/jcifs/src/jcifs/smb/SecurityDescriptor.java +24a25 +> SID owner_user, owner_group; +38c39 +< ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to owner sid +--- +> int ownerUOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to owner sid +40c41 +< ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to group sid +--- +> int ownerGOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to group sid +42c43 +< ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to sacl +--- +> int saclOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to sacl +48,56c49,70 +< bufferIndex++; // revision +< bufferIndex++; +< int size = ServerMessageBlock.readInt2(buffer, bufferIndex); +< bufferIndex += 2; +< int numAces = ServerMessageBlock.readInt4(buffer, bufferIndex); +< bufferIndex += 4; +< +< if (numAces > 4096) +< throw new RuntimeException( "Invalid SecurityDescriptor" ); +--- +> if ( ownerUOffset > 0 ) { +> bufferIndex = start + ownerUOffset; +> owner_user = new SID ( buffer, bufferIndex ); +> bufferIndex += 28; // ??? +> } +> +> if ( ownerGOffset > 0 ) { +> bufferIndex = start + ownerGOffset; +> owner_group = new SID ( buffer, bufferIndex ); +> bufferIndex += 28; // ??? +> } +> +> if ( daclOffset > 0 ) { +> bufferIndex++; // revision +> bufferIndex++; +> int size = ServerMessageBlock.readInt2(buffer, bufferIndex); +> bufferIndex += 2; +> int numAces = ServerMessageBlock.readInt4(buffer, bufferIndex); +> bufferIndex += 4; +> +> if (numAces > 4096) +> throw new RuntimeException( "Invalid SecurityDescriptor" ); +58,59c72,73 +< aces = new ACE[numAces]; +< for (int i = 0; i < numAces; i++) { +--- +> aces = new ACE[numAces]; +> for (int i = 0; i < numAces; i++) { +61a76 +> } +63d77 +< +Only in workspace/jcifs/src/jcifs/smb: SecurityDescriptor.java~ +diff -r temp/jcifs_1.2.13/src/jcifs/smb/SmbFile.java workspace/jcifs/src/jcifs/smb/SmbFile.java +2722a2723,2752 +> +> public SID getOwnerUser() throws IOException { +> int f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 ); +> +> /* +> * NtTrans Query Security Desc Request / Response +> */ +> +> NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x01 ); +> NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse(); +> send( request, response ); +> +> close( f, 0L ); +> return response.securityDescriptor.owner_user; +> } +> +> public SID getOwnerGroup() throws IOException { +> int f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 ); +> +> /* +> * NtTrans Query Security Desc Request / Response +> */ +> +> NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x02 ); +> NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse(); +> send( request, response ); +> +> close( f, 0L ); +> return response.securityDescriptor.owner_group; +> } diff --git a/patches/LargeReadWrite.patch b/patches/LargeReadWrite.patch new file mode 100644 index 0000000..4438cb0 --- /dev/null +++ b/patches/LargeReadWrite.patch @@ -0,0 +1,131 @@ +diff -Naur ../jcifs_1.2.6_org/src/jcifs/smb/SmbConstants.java src/jcifs/smb/SmbConstants.java +--- ../jcifs_1.2.6_org/src/jcifs/smb/SmbConstants.java Fri Oct 07 17:56:54 2005 ++++ src/jcifs/smb/SmbConstants.java Tue Oct 18 12:16:06 2005 +@@ -13,7 +13,7 @@ + static final int DEFAULT_RESPONSE_TIMEOUT = 10000; + static final int DEFAULT_SO_TIMEOUT = 15000; + static final int DEFAULT_RCV_BUF_SIZE = 60416; +- static final int DEFAULT_SND_BUF_SIZE = 16644; ++ static final int DEFAULT_SND_BUF_SIZE = 60416; + static final int DEFAULT_SSN_LIMIT = 250; + + static final InetAddress LADDR = Config.getLocalHost(); +@@ -61,6 +61,8 @@ + static final int CAP_LOCK_AND_READ = 0x0100; + static final int CAP_NT_FIND = 0x0200; + static final int CAP_DFS = 0x1000; ++ static final int CAP_LARGE_READX = 0x4000; ++ static final int CAP_LARGE_WRITEX = 0x8000; + + // file attribute encoding + static final int ATTR_READONLY = 0x01; +@@ -117,7 +119,10 @@ + ( USE_NTSMBS ? CAP_NT_SMBS : 0 ) | + ( USE_NTSTATUS ? CAP_STATUS32 : 0 ) | + ( USE_UNICODE ? CAP_UNICODE : 0 ) | +- CAP_DFS; ++ CAP_DFS | ++ CAP_LARGE_READX | ++ CAP_LARGE_WRITEX; ++ + static final int FLAGS2 = Config.getInt( "jcifs.smb.client.flags2", DEFAULT_FLAGS2 ); + static final int CAPABILITIES = Config.getInt( "jcifs.smb.client.capabilities", DEFAULT_CAPABILITIES ); + static final boolean TCP_NODELAY = Config.getBoolean( "jcifs.smb.client.tcpNoDelay", false ); +diff -Naur ../jcifs_1.2.6_org/src/jcifs/smb/SmbFileInputStream.java src/jcifs/smb/SmbFileInputStream.java +--- ../jcifs_1.2.6_org/src/jcifs/smb/SmbFileInputStream.java Fri Oct 07 17:56:54 2005 ++++ src/jcifs/smb/SmbFileInputStream.java Wed Oct 19 14:00:24 2005 +@@ -32,6 +32,7 @@ + + private long fp; + private int readSize, openFlags; ++ private int readSizeFile; + private byte[] tmp = new byte[1]; + + SmbFile file; +@@ -73,6 +74,12 @@ + } + readSize = Math.min( file.tree.session.transport.rcv_buf_size - 70, + file.tree.session.transport.server.maxBufferSize - 70 ); ++ ++ if(file.tree.session.transport.hasCapability(SmbConstants.CAP_LARGE_READX)) { ++ readSizeFile = Math.min(SmbConstants.RCV_BUF_SIZE - 70, 0xF000); ++ } else { ++ readSizeFile = readSize; ++ } + } + + /** +@@ -143,7 +150,9 @@ + + int r, n; + do { +- r = len > readSize ? readSize : len; ++ int blockSize = (file.getType() == SmbFile.TYPE_FILESYSTEM) ? readSizeFile : readSize; ++ ++ r = len > blockSize ? blockSize : len; + + if( file.log.level > 2 ) + file.log.println( "read: len=" + len + ",r=" + r + ",fp=" + fp ); +diff -Naur ../jcifs_1.2.6_org/src/jcifs/smb/SmbFileOutputStream.java src/jcifs/smb/SmbFileOutputStream.java +--- ../jcifs_1.2.6_org/src/jcifs/smb/SmbFileOutputStream.java Fri Oct 07 17:56:54 2005 ++++ src/jcifs/smb/SmbFileOutputStream.java Wed Oct 19 13:57:14 2005 +@@ -34,6 +34,7 @@ + private SmbFile file; + private boolean append, useNTSmbs; + private int openFlags, writeSize; ++ private int writeSizeFile; + private long fp; + private byte[] tmp = new byte[1]; + private SmbComWriteAndX reqx; +@@ -138,7 +139,14 @@ + } + file.open( openFlags, SmbFile.ATTR_NORMAL, 0 ); + this.openFlags &= ~(SmbFile.O_CREAT | SmbFile.O_TRUNC); /* in case close and reopen */ +- writeSize = file.tree.session.transport.snd_buf_size - 70; ++ writeSize = Math.min( file.tree.session.transport.snd_buf_size - 70, ++ file.tree.session.transport.server.maxBufferSize - 70 ); ++ ++ if(file.tree.session.transport.hasCapability(SmbConstants.CAP_LARGE_WRITEX)) { ++ writeSizeFile = Math.min(SmbConstants.SND_BUF_SIZE - 70, 0xF000); ++ } else { ++ writeSizeFile = writeSize; ++ } + + useNTSmbs = file.tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS ); + if( useNTSmbs ) { +@@ -217,7 +225,9 @@ + + int w; + do { +- w = len > writeSize ? writeSize : len; ++ int blockSize = (file.getType() == SmbFile.TYPE_FILESYSTEM) ? writeSizeFile : writeSize; ++ ++ w = len > blockSize ? blockSize : len; + if( useNTSmbs ) { + reqx.setParam( file.fid, fp, len - w, b, off, w ); + file.send( reqx, rspx ); +diff -Naur ../jcifs_1.2.6_org/src/jcifs/smb/SmbRandomAccessFile.java src/jcifs/smb/SmbRandomAccessFile.java +--- ../jcifs_1.2.6_org/src/jcifs/smb/SmbRandomAccessFile.java Fri Oct 07 17:56:54 2005 ++++ src/jcifs/smb/SmbRandomAccessFile.java Wed Oct 19 14:20:45 2005 +@@ -54,8 +54,20 @@ + throw new IllegalArgumentException( "Invalid mode" ); + } + file.open( openFlags, SmbFile.ATTR_NORMAL, options ); +- readSize = file.tree.session.transport.rcv_buf_size - 70; +- writeSize = file.tree.session.transport.snd_buf_size - 70; ++ ++ if(file.tree.session.transport.hasCapability(SmbConstants.CAP_LARGE_READX)) { ++ readSize = Math.min(SmbConstants.RCV_BUF_SIZE - 70, 0xF000); ++ } else { ++ readSize = file.tree.session.transport.rcv_buf_size - 70; ++ } ++ ++ if(file.tree.session.transport.hasCapability(SmbConstants.CAP_LARGE_WRITEX)) { ++ writeSize = Math.min(SmbConstants.SND_BUF_SIZE - 70, 0xF000); ++ } else { ++ writeSize = Math.min( file.tree.session.transport.snd_buf_size - 70, ++ file.tree.session.transport.server.maxBufferSize - 70 ); ++ } ++ + fp = 0L; + } diff --git a/patches/Print.patch b/patches/Print.patch new file mode 100644 index 0000000..886a695 --- /dev/null +++ b/patches/Print.patch @@ -0,0 +1,115 @@ +diff -Nuar old-src/jcifs/smb/SmbTree.java src/jcifs/smb/SmbTree.java +--- old-src/jcifs/smb/SmbTree.java 2007-01-16 06:00:31.231245500 -0500 ++++ src/jcifs/smb/SmbTree.java 2007-01-16 05:55:40.148493000 -0500 +@@ -90,6 +90,8 @@ + throw new SmbException( "Invalid operation for " + service + " service" ); + } + break; ++ case ServerMessageBlock.SMB_COM_WRITE: ++ if (service.equals("LPT1:")) break; + default: + throw new SmbException( "Invalid operation for " + service + " service" + request ); + } +diff -Nuar old-examples/PrintHtml.java examples/PrintHtml.java +--- old-examples/PrintHtml.java 1969-12-31 19:00:00.000000000 -0500 ++++ examples/PrintHtml.java 2007-01-16 06:07:11.461278000 -0500 +@@ -0,0 +1,99 @@ ++import java.awt.Dimension; ++import java.awt.Graphics; ++import java.awt.Graphics2D; ++ ++import java.awt.print.PageFormat; ++import java.awt.print.Printable; ++ ++import java.io.BufferedReader; ++import java.io.FileReader; ++import java.io.OutputStream; ++import java.io.PrintWriter; ++import java.io.StringWriter; ++ ++import javax.print.Doc; ++import javax.print.DocFlavor; ++import javax.print.DocPrintJob; ++import javax.print.PrintService; ++import javax.print.SimpleDoc; ++import javax.print.StreamPrintServiceFactory; ++ ++import javax.swing.JEditorPane; ++import javax.swing.JFrame; ++import javax.swing.RepaintManager; ++ ++import javax.swing.text.html.HTMLEditorKit; ++ ++import jcifs.Config; ++ ++import jcifs.smb.SmbFileOutputStream; ++ ++public class PrintHtml { ++ ++ public static void main(String[] args) throws Exception { ++ Config.setProperty("jcifs.smb.client.useNTSmbs", "false"); ++ String htmlFile = args[0]; ++ String printerUrl = args[1]; ++ StringWriter collector = new StringWriter(); ++ PrintWriter writer = new PrintWriter(collector); ++ BufferedReader reader = new BufferedReader(new FileReader(htmlFile)); ++ String line; ++ while ((line = reader.readLine()) != null) writer.println(line); ++ writer.flush(); ++ String content = collector.toString(); ++ final JEditorPane pane = new JEditorPane(); ++ pane.setEditorKit(new HTMLEditorKit()); ++ pane.setText(content); ++ JFrame frame = new JFrame(); ++ frame.getContentPane().add(pane); ++ frame.pack(); ++ Printable printable = new Printable() { ++ public int print(Graphics g, PageFormat format, int pageIndex) { ++ RepaintManager currentManager = ++ RepaintManager.currentManager(pane); ++ boolean doubleBuffering = ++ currentManager.isDoubleBufferingEnabled(); ++ if (doubleBuffering) { ++ currentManager.setDoubleBufferingEnabled(false); ++ } ++ try { ++ Dimension size = pane.getSize(); ++ double panelWidth = size.width; ++ double panelHeight = size.height; ++ double pageHeight = format.getImageableHeight(); ++ double pageWidth = format.getImageableWidth(); ++ double scale = pageWidth / panelWidth; ++ int totalNumPages = (int) ++ Math.ceil(scale * panelHeight / pageHeight); ++ if (pageIndex >= totalNumPages) { ++ return Printable.NO_SUCH_PAGE; ++ } ++ Graphics2D g2 = (Graphics2D) g; ++ g2.translate(format.getImageableX(), ++ format.getImageableY()); ++ g2.translate(0f, -pageIndex * pageHeight); ++ g2.scale(scale, scale); ++ pane.paint(g2); ++ return Printable.PAGE_EXISTS; ++ } finally { ++ if (doubleBuffering) { ++ currentManager.setDoubleBufferingEnabled(true); ++ } ++ } ++ } ++ }; ++ DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE; ++ Doc doc = new SimpleDoc(printable, flavor, null); ++ StreamPrintServiceFactory[] factories = ++ StreamPrintServiceFactory.lookupStreamPrintServiceFactories( ++ null, "application/postscript"); ++ OutputStream output = new SmbFileOutputStream(printerUrl); ++ PrintService service = factories[0].getPrintService(output); ++ DocPrintJob job = service.createPrintJob(); ++ job.print(doc, null); ++ output.flush(); ++ output.close(); ++ System.exit(0); ++ } ++ ++} diff --git a/patches/README.txt b/patches/README.txt new file mode 100644 index 0000000..2d20dfd --- /dev/null +++ b/patches/README.txt @@ -0,0 +1,56 @@ +These patches are not supported. They are provided here only for your +conveinience. If you port a patch to a newer version of jCIFS please +resubmit it to the mailing list. + +GetOwnerSid.patch + +This patch adds methods to SmbFile to retrieve the owner SID of the file. + +backup-domain-controllers-1.2.13.patch + +This patch allows multiple comma separated domain controllers to be +specified using the jcifs.http.domainController property. If one is not +'active' another will be tried. + +Eventlog.patch + +This patch adds the necessary MSRPCs to remotely read an event log. + +Print.patch + +This minor patch and example program demonstrates how to emit +PostScript rendered from an AWT/Swing Graphics context and send it +directly to a shared printer. Note that currently you also need to set +jcifs.smb.client.useNTSmbs = false (as otherwise the server spits back +an invalid parameter error). If users determine that this feature works +reliably with a wide variety of printers we will incorporate it into +the distribution (and fix the useNTSmbs goof). + +DnsSrv.patch + +This patch adds JNDI _ldap._tcp.dc._msdcs. lookups so that the +NtlmHttpFilter can use load balancing without jcifs.netbios.wins. + +urlfix.patch + +This patch fixes a bug in URL handling that caused the credentials within +URLs to be unescaped twice causing an authentication error. + +Specifically if using a URL like smb://user:p%25ss@server/path/to/file +where the password should be 'p%ss' it gets unescaped but child SmbFiles +derived from this URL will unsuccessfully try to unescape p%ss again. + +Note: Applications should not use credentials in URLs. Use the +NtlmPasswordAuthentication class instead. + +LargeReadWrite.patch: + +This patch adds two SMBs that supposedly improves read and write +performance considerably. Unfortunately it's not crystal clear +that all implementation properly support the commands. Note that +in addition to this patch an '& 0xFFFF' needs to be added in +SmbTransport.java:doRecv:~437 to appear as: + + int size = Encdec.dec_uint16be( BUF, 2 ) & 0xFFFF; + +although this change has been made in 1.2.7. diff --git a/patches/SetAccessTime.patch b/patches/SetAccessTime.patch new file mode 100644 index 0000000..7d9bab3 --- /dev/null +++ b/patches/SetAccessTime.patch @@ -0,0 +1,101 @@ +--- jcifs_1.3.12/src/jcifs/smb/SmbFile.java ++++ jcifs/src/jcifs/smb/SmbFile.java +@@ -2564,6 +2564,21 @@ + attrExpiration = 0; + } + ++ void setPathInformation( int attrs, long ctime, long atime, long mtime ) throws SmbException { ++ int f, dir; ++ ++ exists(); ++ dir = attributes & ATTR_DIRECTORY; ++ ++ f = open0( O_RDONLY, FILE_WRITE_ATTRIBUTES, ++ dir, dir != 0 ? 0x0001 : 0x0040 ); ++ send( new Trans2SetFileInformation( f, attrs | dir, ctime, atime, mtime ), ++ new Trans2SetFileInformationResponse() ); ++ close( f, 0L ); ++ ++ attrExpiration = 0; ++ } ++ + /** + * Set the create time of the file. The time is specified as milliseconds + * from Jan 1, 1970 which is the same as that which is returned by the +@@ -2581,6 +2596,22 @@ + setPathInformation( 0, time, 0L ); + } + /** ++ * Set the access time of the file. The time is specified as milliseconds ++ * from Jan 1, 1970 which is the same as that which is returned by the ++ * createTime() method. ++ *

++ * This method does not apply to workgroups, servers, or shares. ++ * ++ * @param time the create time as milliseconds since Jan 1, 1970 ++ */ ++ public void setAccessTime( long time ) throws SmbException { ++ if( getUncPath0().length() == 1 ) { ++ throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); ++ } ++ ++ setPathInformation( 0, 0L, time, 0L ); ++ } ++/** + * Set the last modified time of the file. The time is specified as milliseconds + * from Jan 1, 1970 which is the same as that which is returned by the + * lastModified(), getLastModified(), and getDate() methods. +--- jcifs_1.3.12/src/jcifs/smb/Trans2SetFileInformation.java ++++ jcifs/src/jcifs/smb/Trans2SetFileInformation.java +@@ -25,6 +25,7 @@ + private int fid; + private int attributes; + private long createTime, lastWriteTime; ++ private long accessTime; + + Trans2SetFileInformation( int fid, int attributes, long createTime, long lastWriteTime ) { + this.fid = fid; +@@ -38,6 +39,19 @@ + maxSetupCount = (byte)0x00; + } + ++ Trans2SetFileInformation( int fid, int attributes, long createTime, long accessTime, long lastWriteTime ) { ++ this.fid = fid; ++ this.attributes = attributes; ++ this.accessTime = accessTime; ++ this.createTime = createTime; ++ this.lastWriteTime = lastWriteTime; ++ command = SMB_COM_TRANSACTION2; ++ subCommand = TRANS2_SET_FILE_INFORMATION; ++ maxParameterCount = 6; ++ maxDataCount = 0; ++ maxSetupCount = (byte)0x00; ++ } ++ + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; +@@ -58,13 +72,22 @@ + int writeDataWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + ++ // create time + writeTime( createTime, dst, dstIndex ); dstIndex += 8; +- writeInt8( 0L, dst, dstIndex ); dstIndex += 8; ++ ++ // access time ++ writeInt8( accessTime, dst, dstIndex ); dstIndex += 8; ++ ++ // last write time [modification] + writeTime( lastWriteTime, dst, dstIndex ); dstIndex += 8; ++ ++ // change time + writeInt8( 0L, dst, dstIndex ); dstIndex += 8; ++ + /* Samba 2.2.7 needs ATTR_NORMAL + */ + writeInt2( 0x80 | attributes, dst, dstIndex ); dstIndex += 2; ++ + /* 6 zeros observed with NT */ + writeInt8( 0L, dst, dstIndex ); dstIndex += 6; + diff --git a/patches/backup-domain-controllers-1.2.13.patch b/patches/backup-domain-controllers-1.2.13.patch new file mode 100644 index 0000000..fabf6a5 --- /dev/null +++ b/patches/backup-domain-controllers-1.2.13.patch @@ -0,0 +1,69 @@ +diff -Nuarw old/src/jcifs/http/NtlmHttpFilter.java new/src/jcifs/http/NtlmHttpFilter.java +--- old/src/jcifs/http/NtlmHttpFilter.java 2006-12-12 15:00:14.000000000 -0800 ++++ new/src/jcifs/http/NtlmHttpFilter.java 2007-04-03 14:37:25.000000000 -0700 +@@ -24,7 +24,7 @@ + + import java.io.*; + import java.util.Enumeration; +-import java.net.UnknownHostException; ++import java.net.*; + import javax.servlet.*; + import javax.servlet.http.*; + import jcifs.*; +@@ -72,8 +72,26 @@ + Config.setProperty( name, filterConfig.getInitParameter( name )); + } + } ++ + defaultDomain = Config.getProperty("jcifs.smb.client.domain"); + domainController = Config.getProperty( "jcifs.http.domainController" ); ++ if (domainController != null) { ++ String[] domainControllerList = domainController.split(","); ++ ++ if (domainControllerList.length > 1) { ++ String controllerTimeout = Config.getProperty( "jcifs.http.controllerTimeout"); ++ String controllerPort = Config.getProperty("jcifs.http.controllerPort"); ++ int controllerPortInt = controllerPort == null ? 139 : Integer.parseInt(controllerPort); ++ ++ domainController = findActiveController( ++ domainControllerList, ++ Integer.parseInt(controllerTimeout), ++ controllerPortInt); ++ } else { ++ domainController = domainControllerList[0]; ++ } ++ } ++ + if( domainController == null ) { + domainController = defaultDomain; + loadBalance = Config.getBoolean( "jcifs.http.loadBalance", true ); +@@ -118,6 +136,28 @@ + chain.doFilter( new NtlmHttpServletRequest( req, ntlm ), response ); + } + ++ protected String findActiveController( String[] controllerList, ++ int controllerTimeout, ++ int controllerPort) { ++ String activeController = ""; ++ ++ for (int x = 0; x < controllerList.length; x++) { ++ try { ++ activeController = controllerList[x]; ++ InetSocketAddress addr = new InetSocketAddress(activeController, controllerPort); ++ Socket controller = new Socket(); ++ controller.connect(addr, controllerTimeout); ++ controller.setSoLinger(true,1); ++ controller.close(); ++ break; ++ } catch (Exception e) { ++ continue; ++ } ++ } ++ ++ return activeController; ++ } ++ + /** + * Negotiate password hashes with MSIE clients using NTLM SSP + * @param req The servlet request + diff --git a/patches/jcifs_1.2.20c+LsaLookupNames.patch b/patches/jcifs_1.2.20c+LsaLookupNames.patch new file mode 100644 index 0000000..4739c91 --- /dev/null +++ b/patches/jcifs_1.2.20c+LsaLookupNames.patch @@ -0,0 +1,328 @@ +diff -ruNd --strip-trailing-cr jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java +--- jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java 1970-01-01 01:00:00.000000000 +0100 ++++ jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java 2008-04-21 23:54:24.000000000 +0200 +@@ -0,0 +1,16 @@ ++package jcifs.dcerpc.msrpc; ++ ++ ++public class MsrpcLookupNames extends lsarpc.LsarLookupNames { ++ public MsrpcLookupNames(LsaPolicyHandle policyHandle, String names[]) { ++ super( ++ policyHandle, ++ names, ++ (short)1, ++ 0 ++ ); ++ ++ ptype = 0; ++ flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; ++ } ++} +diff -ruNd --strip-trailing-cr jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/lsarpc.java jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/lsarpc.java +--- jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/lsarpc.java 2008-04-25 19:34:39.000000000 +0200 ++++ jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/lsarpc.java 2008-05-23 16:44:42.000000000 +0200 +@@ -1,5 +1,7 @@ + package jcifs.dcerpc.msrpc; + ++import java.nio.charset.Charset; ++ + import jcifs.dcerpc.*; + import jcifs.dcerpc.ndr.*; + +@@ -848,6 +850,93 @@ + retval = (int)_src.dec_ndr_long(); + } + } ++ public static class LsarLookupNames extends DcerpcMessage { ++ protected static final Charset csULU = Charset.forName("UnicodeLittleUnmarked"); ++ ++ public int getOpnum() { return 0x0e; } ++ ++ public int retval; ++ public rpc.policy_handle handle; ++ public String names[]; ++ public LsarRefDomainList domains; ++ public LsarTransSidArray sids; ++ public short level; ++ public int count; ++ ++ public LsarLookupNames( ++ rpc.policy_handle handle, ++ String names[], ++ short level, ++ int count ++ ) { ++ this.handle = handle; ++ this.names = names; ++ this.level = level; ++ this.count = count; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ handle.encode(_dst); ++ ++ _dst.align(4); ++ ++ _dst.enc_ndr_long(names.length); ++ _dst.enc_ndr_long(names.length); ++ ++ for(int i = 0; i < names.length; ++i) { ++ int wlen = 2 * names[i].length(); ++ ++ _dst.enc_ndr_short(wlen); ++ _dst.enc_ndr_short(wlen); ++ _dst.enc_ndr_long(1); ++ } ++ ++ // Encode names ++ for(int i = 0; i < names.length; ++i) { ++ String name = names[i]; ++ int len = name.length(); ++ ++ _dst.enc_ndr_long(len); ++ _dst.enc_ndr_long(0); ++ _dst.enc_ndr_long(len); ++ ++ System.arraycopy( ++ name.getBytes(csULU), 0, ++ _dst.buf, _dst.index, ++ 2 * len ++ ); ++ _dst.advance(2 * len); ++ ++ _dst.align(4); ++ } ++ ++ _dst.enc_ndr_long(0); // num_trans_entries ++ _dst.enc_ndr_long(0); // ptr_trans_sids ++ ++ _dst.enc_ndr_short(level); // lookup_level ++ _dst.align(4); ++ ++ _dst.enc_ndr_long(count); // mapped_count ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ _src.align(4); ++ ++ int _domainsp = _src.dec_ndr_long(); ++ if(_domainsp != 0) { ++ if(domains == null) /* YOYOYO */ ++ domains = new LsarRefDomainList(); ++ domains.decode(_src); ++ } ++ ++ if(sids == null) ++ sids = new LsarTransSidArray(); ++ sids.decode(_src); ++ ++ count = (int)_src.dec_ndr_long(); ++ retval = (int)_src.dec_ndr_long(); ++ } ++ } + public static class LsarOpenPolicy2 extends DcerpcMessage { + + public int getOpnum() { return 0x2c; } +diff -ruNd --strip-trailing-cr jcifs_1.2.20c/src/jcifs/smb/SID.java jcifs_1.2.20c+LsaLookupNames/src/jcifs/smb/SID.java +--- jcifs_1.2.20c/src/jcifs/smb/SID.java 2008-04-25 19:34:39.000000000 +0200 ++++ jcifs_1.2.20c+LsaLookupNames/src/jcifs/smb/SID.java 2008-05-23 16:42:24.000000000 +0200 +@@ -696,5 +696,198 @@ + } + } + } +-} + ++ /** ++ *

This function maps the array of domain object names names to their ++ * equivalent SIDs.

++ * ++ *

Note that the LsaPolicyHandle passed to this function must be created at least ++ * with access 0x00000800 (POLICY_LOOKUP_NAMES), otherwise it will throw an ++ * IOException.

++ * ++ *

On success, the returned SIDs are named according the content of the ++ * names array. Thereby, the case of their acctName fields may ++ * be incorrect since names are mapped ignoring their case. If you want to ++ * obtain the acctName exactly as it is stored in the server, you need ++ * to issue a resolve() call on the SID, or use one of the ++ * various resolveSids() variants. However, the domain part of the names ++ * is always correct, since the server communicates it in its response.

++ * ++ *

Also note that any unresolved name will map to a null value in the related ++ * entry in the returned SIDs array. No exception will be thrown.

++ * ++ * @param handle The DcerpcHandle object to use to communicate with the ++ * LSA service ++ * @param policyHandle The LsaPolicyHandle to use in order to get ++ * authorized by the LSA service. ++ * @param names An array of strings containing the domain's object names to map. ++ * @return An array of SIDs one-to-one related with the given names. ++ * @throws IOException if anything goes wrong ++ * @author Giampaolo Tomassoni <giampaolo at tomassoni dot biz> ++ */ ++ public static SID[] getFromNames( ++ DcerpcHandle handle, ++ LsaPolicyHandle policyHandle, ++ String names[] ++ ) throws IOException { ++ SID outputSids[] = new SID[names.length]; ++ if(names.length > 0) { ++ MsrpcLookupNames rpc = new MsrpcLookupNames(policyHandle, names); ++ handle.sendrecv(rpc); ++ switch (rpc.retval) { ++ case 0: ++ case NtStatus.NT_STATUS_NONE_MAPPED: ++ case 0x00000107: // NT_STATUS_SOME_NOT_MAPPED ++ break; ++ ++ default: ++ throw new SmbException(rpc.retval, false); ++ } ++ ++ SID domainSids[] = new SID[rpc.domains.count]; ++ for(int i = 0; i < domainSids.length; ++i) { ++ SID domainSid = new SID( ++ rpc.domains.domains[i].sid, ++ SID_TYPE_DOMAIN, ++ (new UnicodeString(rpc.domains.domains[i].name, false)).toString(), ++ null, ++ false ++ ); ++ ++ domainSids[i] = domainSid; ++ } ++ ++ for(int i = 0; i < rpc.sids.count; ++i) { ++ SID sid; ++ switch(rpc.sids.sids[i].sid_type) { ++ case SID_TYPE_DOMAIN: ++ sid = domainSids[rpc.sids.sids[i].sid_index]; ++ break; ++ ++ case SID_TYPE_INVALID: ++ case SID_TYPE_UNKNOWN: ++ // Probably the result of an attempt to resolve an ++ // not existent or bad name ++ sid = null; ++ break; ++ ++ default: ++ SID domainSid = domainSids[rpc.sids.sids[i].sid_index]; ++ sid = new SID(domainSid, rpc.sids.sids[i].rid); ++ sid.type = rpc.sids.sids[i].sid_type; ++ sid.domainName = domainSid.domainName; ++ ++ // If the specified name includes domain data, this must be ++ // removed from acctName. ++ sid.acctName = names[i].substring(names[i].indexOf('\\') + 1); ++ } ++ ++ outputSids[i] = sid; ++ } ++ } ++ ++ return(outputSids); ++ } ++ ++ /** ++ *

This function maps the array of domain object names names to their ++ * equivalent SIDs.

++ * ++ *

On success, the returned SIDs are named according the content of the ++ * names array. Thereby, the case of their acctName fields may ++ * be incorrect since names are mapped ignoring their case. If you want to ++ * obtain the acctName exactly as it is stored in the server, you need ++ * to issue a resolve() call on the SID, or use one of the ++ * various resolveSids() variants. However, the domain part of the names ++ * is always correct, since the server communicates it in its response.

++ * ++ *

Also note that any unresolved name will map to a null value in the related ++ * entry in the returned SIDs array. No exception will be thrown.

++ * ++ * @param authorityServerName The name or address of the authority server to ++ * contact to resolve the names. ++ * @param auth The NtlmPasswordAuthentication to use in order to get ++ * authorized by the server. ++ * @param names An array of strings containing the domain's object names to map. ++ * @return An array of SIDs one-to-one related with the given names. ++ * @throws IOException if anything goes wrong ++ * @author Giampaolo Tomassoni <giampaolo at tomassoni dot biz> ++ */ ++ public static SID[] getFromNames( ++ String authorityServerName, ++ NtlmPasswordAuthentication auth, ++ String names[] ++ ) throws IOException { ++ DcerpcHandle handle = DcerpcHandle.getHandle( ++ "ncacn_np:" + authorityServerName + "[\\PIPE\\lsarpc]", ++ auth ++ ); ++ try { ++ int dot = authorityServerName.indexOf('.'); ++ ++ String serverName; ++ if(dot > 0 && !Character.isDigit(authorityServerName.charAt(0))) ++ serverName = authorityServerName.substring(0, dot); ++ else ++ serverName = authorityServerName; ++ ++ LsaPolicyHandle policyHandle = new LsaPolicyHandle( ++ handle, ++ "\\\\" + serverName, ++ 0x00000800 // POLICY_LOOKUP_NAMES ++ ); ++ try { return(getFromNames(handle, policyHandle, names)); } ++ finally { policyHandle.close(); } ++ } finally { handle.close(); } ++ } ++ ++ /** ++ *

This function is like the getFromNames() one, except that it maps a ++ * single name to its SID equivalent.

++ * ++ *

If you have more than one name to map, getFromNames() is much more ++ * efficient.

++ * ++ * @param handle The DcerpcHandle object to use to communicate with the ++ * LSA service ++ * @param policyHandle The LsaPolicyHandle to use in order to get ++ * authorized by the LSA service. ++ * @param name A string containing the domain's object name to map. ++ * @return The SIDs mapped to the given name. ++ * @throws IOException if anything goes wrong ++ * @author Giampaolo Tomassoni <giampaolo at tomassoni dot biz> ++ */ ++ public static SID getFromName( ++ DcerpcHandle handle, ++ LsaPolicyHandle policyHandle, ++ String name ++ ) throws IOException { ++ SID sids[] = getFromNames(handle, policyHandle, new String[] { name }); ++ return(sids == null || sids.length == 0 ? null : sids[0]); ++ } ++ ++ /** ++ *

This function is like the getFromNames() one, except that it maps a ++ * single name to its SID equivalent.

++ * ++ *

If you have more than one name to map, getFromNames() is much more ++ * efficient.

++ * ++ * @param authorityServerName The name or address of the authority server to ++ * contact to resolve the names. ++ * @param auth The NtlmPasswordAuthentication to use in order to get ++ * authorized by the server. ++ * @param name A string containing the domain's object name to map. ++ * @return The SIDs mapped to the given name. ++ * @throws IOException if anything goes wrong ++ * @author Giampaolo Tomassoni <giampaolo at tomassoni dot biz> ++ */ ++ public static SID getFromName( ++ String authorityServerName, ++ NtlmPasswordAuthentication auth, ++ String name ++ ) throws IOException { ++ SID sids[] = getFromNames(authorityServerName, auth, new String[] { name }); ++ return(sids == null || sids.length == 0 ? null : sids[0]); ++ } ++} diff --git a/patches/midl-upton.patch b/patches/midl-upton.patch new file mode 100644 index 0000000..6c4eff7 --- /dev/null +++ b/patches/midl-upton.patch @@ -0,0 +1,106 @@ +diff -wNaur origsrc/emit_dec_java.c src/emit_dec_java.c +--- origsrc/emit_dec_java.c 2008-05-01 11:06:13.000000000 -0700 ++++ src/emit_dec_java.c 2008-05-01 12:13:17.000000000 -0700 +@@ -114,8 +114,8 @@ + if (!is_ref) { + print(idl, indent, "if (_%sp != 0) {\n", name); + if (!IS_PRIMATIVE(sym) && !IS_ARRAY(sym) && !IS_UNION(sym)) { +- print(idl, indent + 4, "if (%s == null) { /* YOYOYO */\n", name); +- print(idl, indent + 8, "%s = new %s();\n", name, sym->out_type); ++ print(idl, indent + 4, "if (%s == null) { /* YOYOYO */\n", sym->name); ++ print(idl, indent + 8, "%s = new %s();\n", sym->name, sym->out_type); + print(idl, indent + 4, "}\n"); + } + } +diff -wNaur origsrc/emit_enc_java.c src/emit_enc_java.c +--- origsrc/emit_enc_java.c 2008-05-01 11:06:13.000000000 -0700 ++++ src/emit_enc_java.c 2008-05-01 12:13:43.000000000 -0700 +@@ -76,7 +76,7 @@ + linkedlist_iterate(siblings, &iter); + while ((mem = linkedlist_next(siblings, &iter))) { + if (strcmp(mem->name, tmp) == 0) { +- if (memcmp(mem->out_type, "Ndr", 3) == 0) { ++ if (mem->out_type != NULL && memcmp(mem->out_type, "Ndr", 3) == 0) { + bp += sprintf(bp, ".value"); + } + break; +@@ -151,7 +151,15 @@ + + buf[0] = '\0'; + if (strcmp(sym->name, sym->orig->name) != 0) { +- sprintf(buf, "%s.", sym->parent->name); ++ sprintf(buf, "%s.", sym->name); ++ int i; ++ // Remove the last component of the name ++ for (i = strlen(buf) - 2; i >= 0; i--) { ++ if (buf[i] == '.') { ++ buf[i+1] = 0; ++ break; ++ } ++ } + } + + if (length_is) { +--- origsrc/parse.c 2008-05-01 11:06:13.000000000 -0700 ++++ src/parse.c 2008-05-01 09:50:45.000000000 -0700 +@@ -39,7 +39,7 @@ + for ( ;; ) { + if (!retok) { + if ((n = tokget(in, tok, tok + TOKMAX)) == -1) { +- AMSG(""); ++ AMSG("Unexpected end of file"); + return -1; + } else if (n == 0) { + break; +@@ -75,8 +75,16 @@ + } + } else if (ch == '(') { + int i; ++ // Count the open we already saw ++ int nestedOpen = 1; + +- for (i = 0; (ch = fgetc(in->in)) != ')' && ch != EOF; i++) { ++ for (i = 0; (ch = fgetc(in->in)) != EOF; i++) { ++ if (ch == '(') { ++ nestedOpen++; ++ } else if (ch == ')') { ++ if (--nestedOpen == 0) ++ break; ++ } + tok[i] = ch; + } + tok[i] = '\0'; +@@ -117,11 +125,11 @@ + s->idl_type = "import"; + s->name = dupstr(tok, idl->al); + s->noemit = 1; +- symaddmem(sym->parent, s); ++ symaddmem(sym, s); + } + + if (idl_process_file(idl, dupstr(buf, idl->al), &iface) == -1) { +- AMSG(""); ++ AMSG("Failed to process import file %s", sym->filename); + return -1; + } + } +@@ -291,7 +299,7 @@ + s->parent = sym; + n = parse(idl, in, s); + if (n == -1) { +- AMSG(""); ++ AMSG("Recursive parse failed"); + return -1; + } else if (n == 0 || n == 3) { + symdel(s); +@@ -305,7 +313,7 @@ + + do { + if ((m = tokget(in, stok, stok + TOKMAX)) < 1) { +- AMSG(""); ++ AMSG("Unexpected end of tokens"); + return m; + } + sch = stok[0]; + + diff --git a/patches/urlfix.patch b/patches/urlfix.patch new file mode 100644 index 0000000..504ed8d --- /dev/null +++ b/patches/urlfix.patch @@ -0,0 +1,144 @@ +diff -Nuar old-src/jcifs/smb/Handler.java src/jcifs/smb/Handler.java +--- old-src/jcifs/smb/Handler.java 2006-12-09 00:31:24.000000000 -0500 ++++ src/jcifs/smb/Handler.java 2006-12-13 06:44:50.813474600 -0500 +@@ -23,50 +23,12 @@ + import java.net.URLStreamHandler; + import java.io.IOException; + import java.io.UnsupportedEncodingException; +- + import java.io.PrintStream; + + public class Handler extends URLStreamHandler { + + static final URLStreamHandler SMB_HANDLER = new Handler(); + +- static String unescape( String str ) throws NumberFormatException, UnsupportedEncodingException { +- char ch; +- int i, j, state, len; +- char[] out; +- byte[] b = new byte[1]; +- +- if( str == null ) { +- return null; +- } +- +- len = str.length(); +- out = new char[len]; +- state = 0; +- for( i = j = 0; i < len; i++ ) { +- switch( state ) { +- case 0: +- ch = str.charAt( i ); +- if( ch == '%' ) { +- state = 1; +- } else { +- out[j++] = ch; +- } +- break; +- case 1: +- /* Get ASCII hex value and convert to platform dependant +- * encoding like EBCDIC perhaps +- */ +- b[0] = (byte)(Integer.parseInt( str.substring( i, i + 2 ), 16 ) & 0xFF); +- out[j++] = (new String( b, 0, 1, "ASCII" )).charAt( 0 ); +- i++; +- state = 0; +- } +- } +- +- return new String( out, 0, j ); +- } +- + protected int getDefaultPort() { + return SmbConstants.DEFAULT_PORT; + } +@@ -75,7 +37,7 @@ + } + protected void parseURL( URL u, String spec, int start, int limit ) { + String host = u.getHost(); +- String userinfo, path, ref; ++ String path, ref; + int port; + + if( spec.equals( "smb://" )) { +@@ -87,13 +49,8 @@ + limit += 2; + } + super.parseURL( u, spec, start, limit ); +- userinfo = u.getUserInfo(); + path = u.getPath(); + ref = u.getRef(); +- try { +- userinfo = unescape( userinfo ); +- } catch( UnsupportedEncodingException uee ) { +- } + if (ref != null) { + path += '#' + ref; + } +@@ -102,7 +59,7 @@ + port = getDefaultPort(); + } + setURL( u, "smb", u.getHost(), port, +- u.getAuthority(), userinfo, ++ u.getAuthority(), u.getUserInfo(), + path, u.getQuery(), null ); + } + } +diff -Nuar old-src/jcifs/smb/NtlmPasswordAuthentication.java src/jcifs/smb/NtlmPasswordAuthentication.java +--- old-src/jcifs/smb/NtlmPasswordAuthentication.java 2006-12-09 00:31:24.000000000 -0500 ++++ src/jcifs/smb/NtlmPasswordAuthentication.java 2006-12-13 06:45:36.884587400 -0500 +@@ -186,6 +186,10 @@ + domain = username = password = null; + + if( userInfo != null ) { ++ try { ++ userInfo = unescape( userInfo ); ++ } catch( UnsupportedEncodingException uee ) { ++ } + int i, u, end; + char c; + +@@ -440,5 +444,43 @@ + public String toString() { + return getName(); + } ++ ++ static String unescape( String str ) throws NumberFormatException, UnsupportedEncodingException { ++ char ch; ++ int i, j, state, len; ++ char[] out; ++ byte[] b = new byte[1]; ++ ++ if( str == null ) { ++ return null; ++ } ++ ++ len = str.length(); ++ out = new char[len]; ++ state = 0; ++ for( i = j = 0; i < len; i++ ) { ++ switch( state ) { ++ case 0: ++ ch = str.charAt( i ); ++ if( ch == '%' ) { ++ state = 1; ++ } else { ++ out[j++] = ch; ++ } ++ break; ++ case 1: ++ /* Get ASCII hex value and convert to platform dependant ++ * encoding like EBCDIC perhaps ++ */ ++ b[0] = (byte)(Integer.parseInt( str.substring( i, i + 2 ), 16 ) & 0xFF); ++ out[j++] = (new String( b, 0, 1, "ASCII" )).charAt( 0 ); ++ i++; ++ state = 0; ++ } ++ } ++ ++ return new String( out, 0, j ); ++ } ++ + } + diff --git a/src/jcifs/Config.java b/src/jcifs/Config.java new file mode 100644 index 0000000..ed9d006 --- /dev/null +++ b/src/jcifs/Config.java @@ -0,0 +1,349 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs; + +import java.util.Properties; +import java.io.*; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.StringTokenizer; +import jcifs.util.LogStream; + +/** + * This class uses a static {@link java.util.Properties} to act + * as a cental repository for all jCIFS configuration properties. It cannot be + * instantiated. Similar to System properties the namespace + * is global therefore property names should be unique. Before use, + * the load method should be called with the name of a + * Properties file (or null indicating no + * file) to initialize the Config. The System + * properties will then populate the Config as well potentially + * overwriting properties from the file. Thus properties provided on the + * commandline with the -Dproperty.name=value VM parameter + * will override properties from the configuration file. + *

+ * There are several ways to set jCIFS properties. See + * the overview page of the API + * documentation for details. + */ + +public class Config { + +public static int socketCount = 0; + + /** + * The static Properties. + */ + + private static Properties prp = new Properties(); + private static LogStream log; + public static String DEFAULT_OEM_ENCODING = "Cp850"; + + static { + String filename; + int level; + FileInputStream in = null; + + log = LogStream.getInstance(); + + try { + filename = System.getProperty( "jcifs.properties" ); + if( filename != null && filename.length() > 1 ) { + in = new FileInputStream( filename ); + } + Config.load( in ); + if (in != null) + in.close(); + } catch( IOException ioe ) { + if( log.level > 0 ) + ioe.printStackTrace( log ); + } + + if(( level = Config.getInt( "jcifs.util.loglevel", -1 )) != -1 ) { + LogStream.setLevel( level ); + } + + try { + "".getBytes(DEFAULT_OEM_ENCODING); + } catch (UnsupportedEncodingException uee) { + if (log.level >= 2) { + log.println("WARNING: The default OEM encoding " + DEFAULT_OEM_ENCODING + + " does not appear to be supported by this JRE. The default encoding will be US-ASCII."); + } + DEFAULT_OEM_ENCODING = "US-ASCII"; + } + + if (log.level >= 4) { + try { + prp.store( log, "JCIFS PROPERTIES" ); + } catch( IOException ioe ) { + } + } + } + + /** + * This static method registers the SMB URL protocol handler which is + * required to use SMB URLs with the java.net.URL class. If this + * method is not called before attempting to create an SMB URL with the + * URL class the following exception will occur: + *

+     * Exception MalformedURLException: unknown protocol: smb
+     *     at java.net.URL.(URL.java:480)
+     *     at java.net.URL.(URL.java:376)
+     *     at java.net.URL.(URL.java:330)
+     *     at jcifs.smb.SmbFile.(SmbFile.java:355)
+     *     ...
+     * 
+ */ + + public static void registerSmbURLHandler() { + String ver, pkgs; + + ver = System.getProperty( "java.version" ); + if( ver.startsWith( "1.1." ) || ver.startsWith( "1.2." )) { + throw new RuntimeException( "jcifs-0.7.0b4+ requires Java 1.3 or above. You are running " + ver ); + } + pkgs = System.getProperty( "java.protocol.handler.pkgs" ); + if( pkgs == null ) { + System.setProperty( "java.protocol.handler.pkgs", "jcifs" ); + } else if( pkgs.indexOf( "jcifs" ) == -1 ) { + pkgs += "|jcifs"; + System.setProperty( "java.protocol.handler.pkgs", pkgs ); + } + } + + // supress javadoc constructor summary by removing 'protected' + Config() {} + + /** + * Set the default properties of the static Properties used by Config. This permits + * a different Properties object/file to be used as the source of properties for + * use by the jCIFS library. The Properties must be set before jCIFS + * classes are accessed as most jCIFS classes load properties statically once. + * Using this method will also override properties loaded + * using the -Djcifs.properties= commandline parameter. + */ + + public static void setProperties( Properties prp ) { + Config.prp = new Properties( prp ); + try { + Config.prp.putAll( System.getProperties() ); + } catch( SecurityException se ) { + if( log.level > 1 ) + log.println( "SecurityException: jcifs will ignore System properties" ); + } + } + + /** + * Load the Config with properties from the stream + * in from a Properties file. + */ + + public static void load( InputStream in ) throws IOException { + if( in != null ) { + prp.load( in ); + } + try { + prp.putAll( System.getProperties() ); + } catch( SecurityException se ) { + if( log.level > 1 ) + log.println( "SecurityException: jcifs will ignore System properties" ); + } + } + + public static void store( OutputStream out, String header ) throws IOException { + prp.store( out, header ); + } + + /** + * List the properties in the Code. + */ + + public static void list( PrintStream out ) throws IOException { + prp.list( out ); + } + + /** + * Add a property. + */ + + public static Object setProperty( String key, String value ) { + return prp.setProperty( key, value ); + } + + /** + * Retrieve a property as an Object. + */ + + public static Object get( String key ) { + return prp.get( key ); + } + + /** + * Retrieve a String. If the key cannot be found, + * the provided def default parameter will be returned. + */ + + public static String getProperty( String key, String def ) { + return prp.getProperty( key, def ); + } + + /** + * Retrieve a String. If the property is not found, null is returned. + */ + + public static String getProperty( String key ) { + return prp.getProperty( key ); + } + + /** + * Retrieve an int. If the key does not exist or + * cannot be converted to an int, the provided default + * argument will be returned. + */ + + public static int getInt( String key, int def ) { + String s = prp.getProperty( key ); + if( s != null ) { + try { + def = Integer.parseInt( s ); + } catch( NumberFormatException nfe ) { + if( log.level > 0 ) + nfe.printStackTrace( log ); + } + } + return def; + } + + /** + * Retrieve an int. If the property is not found, -1 is returned. + */ + + public static int getInt( String key ) { + String s = prp.getProperty( key ); + int result = -1; + if( s != null ) { + try { + result = Integer.parseInt( s ); + } catch( NumberFormatException nfe ) { + if( log.level > 0 ) + nfe.printStackTrace( log ); + } + } + return result; + } + + /** + * Retrieve a long. If the key does not exist or + * cannot be converted to a long, the provided default + * argument will be returned. + */ + + public static long getLong( String key, long def ) { + String s = prp.getProperty( key ); + if( s != null ) { + try { + def = Long.parseLong( s ); + } catch( NumberFormatException nfe ) { + if( log.level > 0 ) + nfe.printStackTrace( log ); + } + } + return def; + } + + /** + * Retrieve an InetAddress. If the address is not + * an IP address and cannot be resolved null will + * be returned. + */ + + public static InetAddress getInetAddress( String key, InetAddress def ) { + String addr = prp.getProperty( key ); + if( addr != null ) { + try { + def = InetAddress.getByName( addr ); + } catch( UnknownHostException uhe ) { + if( log.level > 0 ) { + log.println( addr ); + uhe.printStackTrace( log ); + } + } + } + return def; + } + public static InetAddress getLocalHost() { + String addr = prp.getProperty( "jcifs.smb.client.laddr" ); + + if (addr != null) { + try { + return InetAddress.getByName( addr ); + } catch( UnknownHostException uhe ) { + if( log.level > 0 ) { + log.println( "Ignoring jcifs.smb.client.laddr address: " + addr ); + uhe.printStackTrace( log ); + } + } + } + + return null; + } + + /** + * Retrieve a boolean value. If the property is not found, the value of def is returned. + */ + + public static boolean getBoolean( String key, boolean def ) { + String b = getProperty( key ); + if( b != null ) { + def = b.toLowerCase().equals( "true" ); + } + return def; + } + + /** + * Retrieve an array of InetAddress created from a property + * value containting a delim separated list of hostnames and/or + * ipaddresses. + */ + + public static InetAddress[] getInetAddressArray( String key, String delim, InetAddress[] def ) { + String p = getProperty( key ); + if( p != null ) { + StringTokenizer tok = new StringTokenizer( p, delim ); + int len = tok.countTokens(); + InetAddress[] arr = new InetAddress[len]; + for( int i = 0; i < len; i++ ) { + String addr = tok.nextToken(); + try { + arr[i] = InetAddress.getByName( addr ); + } catch( UnknownHostException uhe ) { + if( log.level > 0 ) { + log.println( addr ); + uhe.printStackTrace( log ); + } + return def; + } + } + return arr; + } + return def; + } +} + diff --git a/src/jcifs/UniAddress.java b/src/jcifs/UniAddress.java new file mode 100644 index 0000000..c6716ad --- /dev/null +++ b/src/jcifs/UniAddress.java @@ -0,0 +1,469 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.io.IOException; +import java.util.StringTokenizer; +import jcifs.netbios.NbtAddress; +import jcifs.netbios.Lmhosts; +import jcifs.util.LogStream; + +/** + *

Under normal conditions it is not necessary to use + * this class to use jCIFS properly. Name resolusion is + * handled internally to the jcifs.smb package. + *

+ * This class is a wrapper for both {@link jcifs.netbios.NbtAddress} + * and {@link java.net.InetAddress}. The name resolution mechanisms + * used will systematically query all available configured resolution + * services including WINS, broadcasts, DNS, and LMHOSTS. See + * Setting Name Resolution Properties + * and the jcifs.resolveOrder property. Changing + * jCIFS name resolution properties can greatly affect the behavior of + * the client and may be necessary for proper operation. + *

+ * This class should be used in favor of InetAddress to resolve + * hostnames on LANs and WANs that support a mixture of NetBIOS/WINS and + * DNS resolvable hosts. + */ + +public class UniAddress { + + private static final int RESOLVER_WINS = 0; + private static final int RESOLVER_BCAST = 1; + private static final int RESOLVER_DNS = 2; + private static final int RESOLVER_LMHOSTS = 3; + + private static int[] resolveOrder; + private static InetAddress baddr; + + private static LogStream log = LogStream.getInstance(); + + static { + String ro = Config.getProperty( "jcifs.resolveOrder" ); + InetAddress nbns = NbtAddress.getWINSAddress(); + + try { + baddr = Config.getInetAddress( "jcifs.netbios.baddr", + InetAddress.getByName( "255.255.255.255" )); + } catch( UnknownHostException uhe ) { + } + + if( ro == null || ro.length() == 0 ) { + + /* No resolveOrder has been specified, use the + * default which is LMHOSTS,WINS,BCAST,DNS or just + * LMHOSTS,BCAST,DNS if jcifs.netbios.wins has not + * been specified. + */ + + if( nbns == null ) { + resolveOrder = new int[3]; + resolveOrder[0] = RESOLVER_LMHOSTS; + resolveOrder[1] = RESOLVER_DNS; + resolveOrder[2] = RESOLVER_BCAST; + } else { + resolveOrder = new int[4]; + resolveOrder[0] = RESOLVER_LMHOSTS; + resolveOrder[1] = RESOLVER_WINS; + resolveOrder[2] = RESOLVER_DNS; + resolveOrder[3] = RESOLVER_BCAST; + } + } else { + int[] tmp = new int[4]; + StringTokenizer st = new StringTokenizer( ro, "," ); + int i = 0; + while( st.hasMoreTokens() ) { + String s = st.nextToken().trim(); + if( s.equalsIgnoreCase( "LMHOSTS" )) { + tmp[i++] = RESOLVER_LMHOSTS; + } else if( s.equalsIgnoreCase( "WINS" )) { + if( nbns == null ) { + if( log.level > 1 ) { + log.println( "UniAddress resolveOrder specifies WINS however the " + + "jcifs.netbios.wins property has not been set" ); + } + continue; + } + tmp[i++] = RESOLVER_WINS; + } else if( s.equalsIgnoreCase( "BCAST" )) { + tmp[i++] = RESOLVER_BCAST; + } else if( s.equalsIgnoreCase( "DNS" )) { + tmp[i++] = RESOLVER_DNS; + } else if( log.level > 1 ) { + log.println( "unknown resolver method: " + s ); + } + } + resolveOrder = new int[i]; + System.arraycopy( tmp, 0, resolveOrder, 0, i ); + } + } + + static class Sem { + Sem( int count ) { + this.count = count; + } + int count; + } + + static class QueryThread extends Thread { + + Sem sem; + String host, scope; + int type; + NbtAddress ans = null; + InetAddress svr; + UnknownHostException uhe; + + QueryThread( Sem sem, String host, int type, + String scope, InetAddress svr ) { + super( "JCIFS-QueryThread: " + host ); + this.sem = sem; + this.host = host; + this.type = type; + this.scope = scope; + this.svr = svr; + } + public void run() { + try { + ans = NbtAddress.getByName( host, type, scope, svr ); + } catch( UnknownHostException uhe ) { + this.uhe = uhe; + } catch( Exception ex ) { + this.uhe = new UnknownHostException( ex.getMessage() ); + } finally { + synchronized( sem ) { + sem.count--; + sem.notify(); + } + } + } + } + + static NbtAddress lookupServerOrWorkgroup( String name, InetAddress svr ) + throws UnknownHostException { + Sem sem = new Sem( 2 ); + int type = NbtAddress.isWINS( svr ) ? 0x1b : 0x1d; + + QueryThread q1x = new QueryThread( sem, name, type, null, svr ); + QueryThread q20 = new QueryThread( sem, name, 0x20, null, svr ); + q1x.setDaemon( true ); + q20.setDaemon( true ); + try { + synchronized( sem ) { + q1x.start(); + q20.start(); + + while( sem.count > 0 && q1x.ans == null && q20.ans == null ) { + sem.wait(); + } + } + } catch( InterruptedException ie ) { + throw new UnknownHostException( name ); + } + if( q1x.ans != null ) { + return q1x.ans; + } else if( q20.ans != null ) { + return q20.ans; + } else { + throw q1x.uhe; + } + } + + /** + * Determines the address of a host given it's host name. The name can be a + * machine name like "jcifs.samba.org", or an IP address like "192.168.1.15". + * + * @param hostname NetBIOS or DNS hostname to resolve + * @throws java.net.UnknownHostException if there is an error resolving the name + */ + + public static UniAddress getByName( String hostname ) + throws UnknownHostException { + return getByName( hostname, false ); + } + + static boolean isDotQuadIP( String hostname ) { + if( Character.isDigit( hostname.charAt( 0 ))) { + int i, len, dots; + char[] data; + + i = dots = 0; /* quick IP address validation */ + len = hostname.length(); + data = hostname.toCharArray(); + while( i < len && Character.isDigit( data[i++] )) { + if( i == len && dots == 3 ) { + // probably an IP address + return true; + } + if( i < len && data[i] == '.' ) { + dots++; + i++; + } + } + } + + return false; + } + + static boolean isAllDigits( String hostname ) { + for (int i = 0; i < hostname.length(); i++) { + if (Character.isDigit( hostname.charAt( i )) == false) { + return false; + } + } + return true; + } + + /** + * Lookup hostname and return it's UniAddress. If the + * possibleNTDomainOrWorkgroup parameter is true an + * addtional name query will be performed to locate a master browser. + */ + + public static UniAddress getByName( String hostname, + boolean possibleNTDomainOrWorkgroup ) + throws UnknownHostException { + UniAddress[] addrs = UniAddress.getAllByName(hostname, possibleNTDomainOrWorkgroup); + return addrs[0]; + } + public static UniAddress[] getAllByName( String hostname, + boolean possibleNTDomainOrWorkgroup ) + throws UnknownHostException { + Object addr; + int i; + + if( hostname == null || hostname.length() == 0 ) { + throw new UnknownHostException(); + } + + if( isDotQuadIP( hostname )) { + UniAddress[] addrs = new UniAddress[1]; + addrs[0] = new UniAddress( NbtAddress.getByName( hostname )); + return addrs; + } + + for( i = 0; i < resolveOrder.length; i++ ) { + try { + switch( resolveOrder[i] ) { + case RESOLVER_LMHOSTS: + if(( addr = Lmhosts.getByName( hostname )) == null ) { + continue; + } + break; + case RESOLVER_WINS: + if( hostname == NbtAddress.MASTER_BROWSER_NAME || + hostname.length() > 15 ) { + // invalid netbios name + continue; + } + if( possibleNTDomainOrWorkgroup ) { + addr = lookupServerOrWorkgroup( hostname, NbtAddress.getWINSAddress() ); + } else { + addr = NbtAddress.getByName( hostname, 0x20, null, NbtAddress.getWINSAddress() ); + } + break; + case RESOLVER_BCAST: + if( hostname.length() > 15 ) { + // invalid netbios name + continue; + } + if( possibleNTDomainOrWorkgroup ) { + addr = lookupServerOrWorkgroup( hostname, baddr ); + } else { + addr = NbtAddress.getByName( hostname, 0x20, null, baddr ); + } + break; + case RESOLVER_DNS: + if( isAllDigits( hostname )) { + throw new UnknownHostException( hostname ); + } + InetAddress[] iaddrs = InetAddress.getAllByName( hostname ); + UniAddress[] addrs = new UniAddress[iaddrs.length]; + for (int ii = 0; ii < iaddrs.length; ii++) { + addrs[ii] = new UniAddress(iaddrs[ii]); + } + return addrs; // Success + default: + throw new UnknownHostException( hostname ); + } + UniAddress[] addrs = new UniAddress[1]; + addrs[0] = new UniAddress( addr ); + return addrs; // Success + } catch( IOException ioe ) { + // Failure + } + } + throw new UnknownHostException( hostname ); + } + + /** + * Perform DNS SRV lookup on successively shorter suffixes of name + * and return successful suffix or throw an UnknownHostException. +import javax.naming.*; +import javax.naming.directory.*; + public static String getDomainByName(String name) throws UnknownHostException { + DirContext context; + UnknownHostException uhe = null; + + try { + context = new InitialDirContext(); + for ( ;; ) { + try { + Attributes attributes = context.getAttributes( + "dns:/_ldap._tcp.dc._msdcs." + name, + new String[] { "SRV" } + ); + return name; + } catch (NameNotFoundException nnfe) { + uhe = new UnknownHostException(nnfe.getMessage()); + } + int dot = name.indexOf('.'); + if (dot == -1) + break; + name = name.substring(dot + 1); + } + } catch (NamingException ne) { + if (log.level > 1) + ne.printStackTrace(log); + } + + throw uhe != null ? uhe : new UnknownHostException("invalid name"); + } + */ + + + Object addr; + String calledName; + + /** + * Create a UniAddress by wrapping an InetAddress or + * NbtAddress. + */ + + public UniAddress( Object addr ) { + if( addr == null ) { + throw new IllegalArgumentException(); + } + this.addr = addr; + } + + /** + * Return the IP address of this address as a 32 bit integer. + */ + + public int hashCode() { + return addr.hashCode(); + } + + /** + * Compare two addresses for equality. Two UniAddresss are equal + * if they are both UniAddress' and refer to the same IP address. + */ + public boolean equals( Object obj ) { + return obj instanceof UniAddress && addr.equals(((UniAddress)obj).addr); + } +/* + public boolean equals( Object obj ) { + return obj instanceof UniAddress && addr.hashCode() == obj.hashCode(); + } +*/ + + /** + * Guess first called name to try for session establishment. This + * method is used exclusively by the jcifs.smb package. + */ + + public String firstCalledName() { + if( addr instanceof NbtAddress ) { + return ((NbtAddress)addr).firstCalledName(); + } else { + calledName = ((InetAddress)addr).getHostName(); + if( isDotQuadIP( calledName )) { + calledName = NbtAddress.SMBSERVER_NAME; + } else { + int i = calledName.indexOf( '.' ); + if( i > 1 && i < 15 ) { + calledName = calledName.substring( 0, i ).toUpperCase(); + } else if( calledName.length() > 15 ) { + calledName = NbtAddress.SMBSERVER_NAME; + } else { + calledName = calledName.toUpperCase(); + } + } + } + + return calledName; + } + + /** + * Guess next called name to try for session establishment. This + * method is used exclusively by the jcifs.smb package. + */ + + public String nextCalledName() { + if( addr instanceof NbtAddress ) { + return ((NbtAddress)addr).nextCalledName(); + } else if( calledName != NbtAddress.SMBSERVER_NAME ) { + calledName = NbtAddress.SMBSERVER_NAME; + return calledName; + } + return null; + } + + /** + * Return the underlying NbtAddress or InetAddress. + */ + + public Object getAddress() { + return addr; + } + + /** + * Return the hostname of this address such as "MYCOMPUTER". + */ + + public String getHostName() { + if( addr instanceof NbtAddress ) { + return ((NbtAddress)addr).getHostName(); + } + return ((InetAddress)addr).getHostName(); + } + + /** + * Return the IP address as text such as "192.168.1.15". + */ + + public String getHostAddress() { + if( addr instanceof NbtAddress ) { + return ((NbtAddress)addr).getHostAddress(); + } + return ((InetAddress)addr).getHostAddress(); + } + + /** + * Return the a text representation of this address such as + * MYCOMPUTER/192.168.1.15. + */ + public String toString() { + return addr.toString(); + } +} diff --git a/src/jcifs/dcerpc/DcerpcBind.java b/src/jcifs/dcerpc/DcerpcBind.java new file mode 100644 index 0000000..b09e19f --- /dev/null +++ b/src/jcifs/dcerpc/DcerpcBind.java @@ -0,0 +1,89 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +import jcifs.dcerpc.ndr.*; + +public class DcerpcBind extends DcerpcMessage { + + static final String[] result_message = { + "0", + "DCERPC_BIND_ERR_ABSTRACT_SYNTAX_NOT_SUPPORTED", + "DCERPC_BIND_ERR_PROPOSED_TRANSFER_SYNTAXES_NOT_SUPPORTED", + "DCERPC_BIND_ERR_LOCAL_LIMIT_EXCEEDED" + }; + + static String getResultMessage(int result) { + return result < 4 ? + result_message[result] : + "0x" + jcifs.util.Hexdump.toHexString(result, 4); + } + public DcerpcException getResult() { + if (result != 0) + return new DcerpcException(getResultMessage(result)); + return null; + } + + DcerpcBinding binding; + int max_xmit, max_recv; + + public DcerpcBind() { + } + DcerpcBind(DcerpcBinding binding, DcerpcHandle handle) { + this.binding = binding; + max_xmit = handle.max_xmit; + max_recv = handle.max_recv; + ptype = 11; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } + + public int getOpnum() { + return 0; + } + public void encode_in(NdrBuffer buf) throws NdrException { + buf.enc_ndr_short(max_xmit); + buf.enc_ndr_short(max_recv); + buf.enc_ndr_long(0); /* assoc. group */ + buf.enc_ndr_small(1); /* num context items */ + buf.enc_ndr_small(0); /* reserved */ + buf.enc_ndr_short(0); /* reserved2 */ + buf.enc_ndr_short(0); /* context id */ + buf.enc_ndr_small(1); /* number of items */ + buf.enc_ndr_small(0); /* reserved */ + binding.uuid.encode(buf); + buf.enc_ndr_short(binding.major); + buf.enc_ndr_short(binding.minor); + DCERPC_UUID_SYNTAX_NDR.encode(buf); + buf.enc_ndr_long(2); /* syntax version */ + } + public void decode_out(NdrBuffer buf) throws NdrException { + buf.dec_ndr_short(); /* max transmit frag size */ + buf.dec_ndr_short(); /* max receive frag size */ + buf.dec_ndr_long(); /* assoc. group */ + int n = buf.dec_ndr_short(); /* secondary addr len */ + buf.advance(n); /* secondary addr */ + buf.align(4); + buf.dec_ndr_small(); /* num results */ + buf.align(4); + result = buf.dec_ndr_short(); + buf.dec_ndr_short(); + buf.advance(20); /* transfer syntax / version */ + } +} diff --git a/src/jcifs/dcerpc/DcerpcBinding.java b/src/jcifs/dcerpc/DcerpcBinding.java new file mode 100644 index 0000000..5cade3f --- /dev/null +++ b/src/jcifs/dcerpc/DcerpcBinding.java @@ -0,0 +1,99 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +import java.util.HashMap; +import java.util.Iterator; + +import jcifs.dcerpc.msrpc.*; + +public class DcerpcBinding { + + private static HashMap INTERFACES; + + static { + INTERFACES = new HashMap(); + INTERFACES.put("srvsvc", srvsvc.getSyntax()); + INTERFACES.put("lsarpc", lsarpc.getSyntax()); + INTERFACES.put("samr", samr.getSyntax()); + INTERFACES.put("netdfs", netdfs.getSyntax()); + } + + public static void addInterface(String name, String syntax) + { + INTERFACES.put(name, syntax); + } + + String proto; + String server; + String endpoint = null; + HashMap options = null; + UUID uuid = null; + int major; + int minor; + + DcerpcBinding(String proto, String server) { + this.proto = proto; + this.server = server; + } + + void setOption(String key, Object val) throws DcerpcException { + if (key.equals("endpoint")) { + endpoint = val.toString().toLowerCase(); + if (endpoint.startsWith("\\pipe\\")) { + String iface = (String)INTERFACES.get(endpoint.substring(6)); + if (iface != null) { + int c, p; + c = iface.indexOf(':'); + p = iface.indexOf('.', c + 1); + uuid = new UUID(iface.substring(0, c)); + major = Integer.parseInt(iface.substring(c + 1, p)); + minor = Integer.parseInt(iface.substring(p + 1)); + return; + } + } + throw new DcerpcException("Bad endpoint: " + endpoint); + } + if (options == null) + options = new HashMap(); + options.put(key, val); + } + Object getOption(String key) { + if (key.equals("endpoint")) + return endpoint; + if (options != null) + return options.get(key); + return null; + } + + public String toString() { + String ret = proto + ":" + server + "[" + endpoint; + if (options != null) { + Iterator iter = options.keySet().iterator(); + while (iter.hasNext()) { + Object key = iter.next(); + Object val = options.get(key); + ret += "," + key + "=" + val; + } + } + ret += "]"; + return ret; + } +} diff --git a/src/jcifs/dcerpc/DcerpcConstants.java b/src/jcifs/dcerpc/DcerpcConstants.java new file mode 100644 index 0000000..f0b1100 --- /dev/null +++ b/src/jcifs/dcerpc/DcerpcConstants.java @@ -0,0 +1,34 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +public interface DcerpcConstants { + + public static final UUID DCERPC_UUID_SYNTAX_NDR = new UUID("8a885d04-1ceb-11c9-9fe8-08002b104860"); + + public static final int DCERPC_FIRST_FRAG = 0x01; /* First fragment */ + public static final int DCERPC_LAST_FRAG = 0x02; /* Last fragment */ + public static final int DCERPC_PENDING_CANCEL = 0x04; /* Cancel was pending at sender */ + public static final int DCERPC_RESERVED_1 = 0x08; + public static final int DCERPC_CONC_MPX = 0x10; /* supports concurrent multiplexing */ + public static final int DCERPC_DID_NOT_EXECUTE = 0x20; + public static final int DCERPC_MAYBE = 0x40; /* `maybe' call semantics requested */ + public static final int DCERPC_OBJECT_UUID = 0x80; /* if true, a non-nil object UUID */ +} diff --git a/src/jcifs/dcerpc/DcerpcError.java b/src/jcifs/dcerpc/DcerpcError.java new file mode 100644 index 0000000..0bd4a69 --- /dev/null +++ b/src/jcifs/dcerpc/DcerpcError.java @@ -0,0 +1,58 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +public interface DcerpcError { + + public static final int DCERPC_FAULT_OTHER = 0x00000001; + public static final int DCERPC_FAULT_ACCESS_DENIED = 0x00000005; + public static final int DCERPC_FAULT_CANT_PERFORM = 0x000006D8; + public static final int DCERPC_FAULT_NDR = 0x000006F7; + public static final int DCERPC_FAULT_INVALID_TAG = 0x1C000006; + public static final int DCERPC_FAULT_CONTEXT_MISMATCH = 0x1C00001A; + public static final int DCERPC_FAULT_OP_RNG_ERROR = 0x1C010002; + public static final int DCERPC_FAULT_UNK_IF = 0x1C010003; + public static final int DCERPC_FAULT_PROTO_ERROR = 0x1c01000b; + + static final int[] DCERPC_FAULT_CODES = { + DCERPC_FAULT_OTHER, + DCERPC_FAULT_ACCESS_DENIED, + DCERPC_FAULT_CANT_PERFORM, + DCERPC_FAULT_NDR, + DCERPC_FAULT_INVALID_TAG, + DCERPC_FAULT_CONTEXT_MISMATCH, + DCERPC_FAULT_OP_RNG_ERROR, + DCERPC_FAULT_UNK_IF, + DCERPC_FAULT_PROTO_ERROR + }; + + static final String[] DCERPC_FAULT_MESSAGES = { + "DCERPC_FAULT_OTHER", + "DCERPC_FAULT_ACCESS_DENIED", + "DCERPC_FAULT_CANT_PERFORM", + "DCERPC_FAULT_NDR", + "DCERPC_FAULT_INVALID_TAG", + "DCERPC_FAULT_CONTEXT_MISMATCH", + "DCERPC_FAULT_OP_RNG_ERROR", + "DCERPC_FAULT_UNK_IF", + "DCERPC_FAULT_PROTO_ERROR" + }; +} + diff --git a/src/jcifs/dcerpc/DcerpcException.java b/src/jcifs/dcerpc/DcerpcException.java new file mode 100644 index 0000000..e6f8cbe --- /dev/null +++ b/src/jcifs/dcerpc/DcerpcException.java @@ -0,0 +1,77 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +import java.io.*; + +import jcifs.util.Hexdump; +import jcifs.smb.WinError; + +public class DcerpcException extends IOException implements DcerpcError, WinError { + + static String getMessageByDcerpcError(int errcode) { + int min = 0; + int max = DCERPC_FAULT_CODES.length; + + while (max >= min) { + int mid = (min + max) / 2; + + if (errcode > DCERPC_FAULT_CODES[mid]) { + min = mid + 1; + } else if (errcode < DCERPC_FAULT_CODES[mid]) { + max = mid - 1; + } else { + return DCERPC_FAULT_MESSAGES[mid]; + } + } + + return "0x" + Hexdump.toHexString(errcode, 8); + } + + private int error; + private Throwable rootCause; + + DcerpcException(int error) { + super(getMessageByDcerpcError(error)); + this.error = error; + } + public DcerpcException(String msg) { + super(msg); + } + public DcerpcException(String msg, Throwable rootCause) { + super(msg); + this.rootCause = rootCause; + } + public int getErrorCode() { + return error; + } + public Throwable getRootCause() { + return rootCause; + } + public String toString() { + if (rootCause != null) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + rootCause.printStackTrace(pw); + return super.toString() + "\n" + sw; + } + return super.toString(); + } +} diff --git a/src/jcifs/dcerpc/DcerpcHandle.java b/src/jcifs/dcerpc/DcerpcHandle.java new file mode 100644 index 0000000..1182ab3 --- /dev/null +++ b/src/jcifs/dcerpc/DcerpcHandle.java @@ -0,0 +1,268 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +import java.io.*; +import java.net.*; +import java.security.Principal; + +import jcifs.smb.NtlmPasswordAuthentication; +import jcifs.util.Hexdump; +import jcifs.dcerpc.ndr.NdrBuffer; + +public abstract class DcerpcHandle implements DcerpcConstants { + + /* Bindings are in the form: + * proto:\\server[key1=val1,key2=val2] + * or + * proto:server[key1=val1,key2=val2] + * or + * proto:[key1=val1,key2=val2] + * + * If a key is absent it is assumed to be 'endpoint'. Thus the + * following are equivalent: + * proto:\\ts0.win.net[endpoint=\pipe\srvsvc] + * proto:ts0.win.net[\pipe\srvsvc] + * + * If the server is absent it is set to "127.0.0.1" + */ + protected static DcerpcBinding parseBinding(String str) throws DcerpcException { + int state, mark, si; + char[] arr = str.toCharArray(); + String proto = null, key = null; + DcerpcBinding binding = null; + + state = mark = si = 0; + do { + char ch = arr[si]; + + switch (state) { + case 0: + if (ch == ':') { + proto = str.substring(mark, si); + mark = si + 1; + state = 1; + } + break; + case 1: + if (ch == '\\') { + mark = si + 1; + break; + } + state = 2; + case 2: + if (ch == '[') { + String server = str.substring(mark, si).trim(); + if (server.length() == 0) + server = "127.0.0.1"; + binding = new DcerpcBinding(proto, str.substring(mark, si)); + mark = si + 1; + state = 5; + } + break; + case 5: + if (ch == '=') { + key = str.substring(mark, si).trim(); + mark = si + 1; + } else if (ch == ',' || ch == ']') { + String val = str.substring(mark, si).trim(); + if (key == null) + key = "endpoint"; + binding.setOption(key, val); + key = null; + } + break; + default: + si = arr.length; + } + + si++; + } while (si < arr.length); + + if (binding == null || binding.endpoint == null) + throw new DcerpcException("Invalid binding URL: " + str); + + return binding; + } + + protected DcerpcBinding binding; + protected int max_xmit = 4280; + protected int max_recv = max_xmit; + protected int state = 0; + protected DcerpcSecurityProvider securityProvider = null; + private static int call_id = 1; + + public static DcerpcHandle getHandle(String url, + NtlmPasswordAuthentication auth) + throws UnknownHostException, MalformedURLException, DcerpcException { + if (url.startsWith("ncacn_np:")) { + return new DcerpcPipeHandle(url, auth); + } + throw new DcerpcException("DCERPC transport not supported: " + url); + } + + public void bind() throws DcerpcException, IOException { +synchronized (this) { + try { + state = 1; + DcerpcMessage bind = new DcerpcBind(binding, this); + sendrecv(bind); + } catch (IOException ioe) { + state = 0; + throw ioe; + } +} + } + public void sendrecv(DcerpcMessage msg) throws DcerpcException, IOException { + byte[] stub, frag; + NdrBuffer buf, fbuf; + boolean isLast, isDirect; + DcerpcException de; + + if (state == 0) { + bind(); + } + + isDirect = msg instanceof DcerpcBind; + + stub = jcifs.smb.BufferCache.getBuffer(); + try { + int off, tot, n; + + buf = new NdrBuffer(stub, 0); + + msg.flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + msg.call_id = call_id; + + msg.encode(buf); + + if (securityProvider != null) { + buf.setIndex(0); + securityProvider.wrap(buf); + } + + tot = buf.getLength(); + off = 0; + + while (off < tot) { + msg.call_id = call_id++; + + if ((tot - off) > max_xmit) { + /* Multiple fragments. Need to set flags and length + * and re-encode header + msg.length = n = max_xmit; + msg.flags &= ~DCERPC_LAST_FRAG; + buf.start = off; + buf.reset(); + msg.encode_header(buf); + */ + throw new DcerpcException("Fragmented request PDUs currently not supported"); + } else { + n = tot - off; + } + + doSendFragment(stub, off, n, isDirect); + off += n; + } + + doReceiveFragment(stub, isDirect); + buf.reset(); + buf.setIndex(8); + buf.setLength(buf.dec_ndr_short()); + + if (securityProvider != null) + securityProvider.unwrap(buf); + + buf.setIndex(0); + + msg.decode_header(buf); + + off = 24; + if (msg.ptype == 2 && msg.isFlagSet(DCERPC_LAST_FRAG) == false) + off = msg.length; + + frag = null; + fbuf = null; + while (msg.isFlagSet(DCERPC_LAST_FRAG) == false) { + int stub_frag_len; + + if (frag == null) { + frag = new byte[max_recv]; + fbuf = new NdrBuffer(frag, 0); + } + + doReceiveFragment(frag, isDirect); + fbuf.reset(); + fbuf.setIndex(8); + fbuf.setLength(fbuf.dec_ndr_short()); + + if (securityProvider != null) + securityProvider.unwrap(fbuf); + + fbuf.reset(); + msg.decode_header(fbuf); + stub_frag_len = msg.length - 24; + + if ((off + stub_frag_len) > stub.length) { + // shouldn't happen if alloc_hint is correct or greater + byte[] tmp = new byte[off + stub_frag_len]; + System.arraycopy(stub, 0, tmp, 0, off); + stub = tmp; + } + + System.arraycopy(frag, 24, stub, off, stub_frag_len); + off += stub_frag_len; + } + + buf = new NdrBuffer(stub, 0); + msg.decode(buf); + } finally { + jcifs.smb.BufferCache.releaseBuffer(stub); + } + + if ((de = msg.getResult()) != null) + throw de; + } + + public void setDcerpcSecurityProvider(DcerpcSecurityProvider securityProvider) + { + this.securityProvider = securityProvider; + } + public String getServer() { + if (this instanceof DcerpcPipeHandle) + return ((DcerpcPipeHandle)this).pipe.getServer(); + return null; + } + public Principal getPrincipal() { + if (this instanceof DcerpcPipeHandle) + return ((DcerpcPipeHandle)this).pipe.getPrincipal(); + return null; + } + public String toString() { + return binding.toString(); + } + + protected abstract void doSendFragment(byte[] buf, + int off, + int length, + boolean isDirect) throws IOException; + protected abstract void doReceiveFragment(byte[] buf, boolean isDirect) throws IOException; + public abstract void close() throws IOException; +} diff --git a/src/jcifs/dcerpc/DcerpcMessage.java b/src/jcifs/dcerpc/DcerpcMessage.java new file mode 100644 index 0000000..980dcf2 --- /dev/null +++ b/src/jcifs/dcerpc/DcerpcMessage.java @@ -0,0 +1,118 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +import java.io.IOException; +import jcifs.dcerpc.ndr.*; + +public abstract class DcerpcMessage extends NdrObject implements DcerpcConstants { + + protected int ptype = -1; + protected int flags = 0; + protected int length = 0; + protected int call_id = 0; + protected int alloc_hint = 0; + protected int result = 0; + + public boolean isFlagSet(int flag) { + return (flags & flag) == flag; + } + public void unsetFlag(int flag) { + flags |= flag; + } + public void setFlag(int flag) { + flags |= flag; + } + public DcerpcException getResult() { + if (result != 0) + return new DcerpcException(result); + return null; + } + + void encode_header(NdrBuffer buf) { + buf.enc_ndr_small(5); /* RPC version */ + buf.enc_ndr_small(0); /* minor version */ + buf.enc_ndr_small(ptype); + buf.enc_ndr_small(flags); + buf.enc_ndr_long(0x00000010); /* Little-endian / ASCII / IEEE */ + buf.enc_ndr_short(length); + buf.enc_ndr_short(0); /* length of auth_value */ + buf.enc_ndr_long(call_id); + } + void decode_header(NdrBuffer buf) throws NdrException { + /* RPC major / minor version */ + if (buf.dec_ndr_small() != 5 || buf.dec_ndr_small() != 0) + throw new NdrException("DCERPC version not supported"); + ptype = buf.dec_ndr_small(); + flags = buf.dec_ndr_small(); + if (buf.dec_ndr_long() != 0x00000010) /* Little-endian / ASCII / IEEE */ + throw new NdrException("Data representation not supported"); + length = buf.dec_ndr_short(); + if (buf.dec_ndr_short() != 0) + throw new NdrException("DCERPC authentication not supported"); + call_id = buf.dec_ndr_long(); + } + public void encode(NdrBuffer buf) throws NdrException { + int start = buf.getIndex(); + int alloc_hint_index = 0; + + buf.advance(16); /* momentarily skip header */ + if (ptype == 0) { /* Request */ + alloc_hint_index = buf.getIndex(); + buf.enc_ndr_long(0); /* momentarily skip alloc hint */ + buf.enc_ndr_short(0); /* context id */ + buf.enc_ndr_short(getOpnum()); + } + + encode_in(buf); + length = buf.getIndex() - start; + + if (ptype == 0) { + buf.setIndex(alloc_hint_index); + alloc_hint = length - alloc_hint_index; + buf.enc_ndr_long(alloc_hint); + } + + buf.setIndex(start); + encode_header(buf); + buf.setIndex(start + length); + } + public void decode(NdrBuffer buf) throws NdrException { + decode_header(buf); + + if (ptype != 12 && ptype != 2 && ptype != 3 && ptype != 13) + throw new NdrException("Unexpected ptype: " + ptype); + + if (ptype == 2 || ptype == 3) { /* Response or Fault */ + alloc_hint = buf.dec_ndr_long(); + buf.dec_ndr_short(); /* context id */ + buf.dec_ndr_short(); /* cancel count */ + } + if (ptype == 3 || ptype == 13) { /* Fault */ + result = buf.dec_ndr_long(); + } else { /* Bind_ack or Response */ + decode_out(buf); + } + } + + public abstract int getOpnum(); + public abstract void encode_in(NdrBuffer buf) throws NdrException; + public abstract void decode_out(NdrBuffer buf) throws NdrException; +} diff --git a/src/jcifs/dcerpc/DcerpcPipeHandle.java b/src/jcifs/dcerpc/DcerpcPipeHandle.java new file mode 100644 index 0000000..c37a5f5 --- /dev/null +++ b/src/jcifs/dcerpc/DcerpcPipeHandle.java @@ -0,0 +1,108 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +import java.net.*; +import java.io.*; + +import jcifs.dcerpc.ndr.NdrBuffer; +import jcifs.smb.*; +import jcifs.util.*; + +public class DcerpcPipeHandle extends DcerpcHandle { + + SmbNamedPipe pipe; + SmbFileInputStream in = null; + SmbFileOutputStream out = null; + boolean isStart = true; + + public DcerpcPipeHandle(String url, + NtlmPasswordAuthentication auth) + throws UnknownHostException, MalformedURLException, DcerpcException { + binding = DcerpcHandle.parseBinding(url); + url = "smb://" + binding.server + "/IPC$/" + binding.endpoint.substring(6); + + String params = "", server, address; + server = (String)binding.getOption("server"); + if (server != null) + params += "&server=" + server; + address = (String)binding.getOption("address"); + if (server != null) + params += "&address=" + address; + if (params.length() > 0) + url += "?" + params.substring(1); + + pipe = new SmbNamedPipe(url, + /* This 0x20000 bit is going to get chopped! */ + (0x2019F << 16) | SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT, + auth); + } + + protected void doSendFragment(byte[] buf, + int off, + int length, + boolean isDirect) throws IOException { + if (out != null && out.isOpen() == false) + throw new IOException("DCERPC pipe is no longer open"); + + if (in == null) + in = (SmbFileInputStream)pipe.getNamedPipeInputStream(); + if (out == null) + out = (SmbFileOutputStream)pipe.getNamedPipeOutputStream(); + if (isDirect) { + out.writeDirect( buf, off, length, 1 ); + return; + } + out.write(buf, off, length); + } + protected void doReceiveFragment(byte[] buf, boolean isDirect) throws IOException { + int off, flags, length; + + if (buf.length < max_recv) + throw new IllegalArgumentException("buffer too small"); + + if (isStart && !isDirect) { // start of new frag, do trans + off = in.read(buf, 0, 1024); + } else { + off = in.readDirect(buf, 0, buf.length); + } + + if (buf[0] != 5 && buf[1] != 0) + throw new IOException("Unexpected DCERPC PDU header"); + + flags = buf[3] & 0xFF; + // next read is start of new frag + isStart = (flags & DCERPC_LAST_FRAG) == DCERPC_LAST_FRAG; + + length = Encdec.dec_uint16le(buf, 8); + if (length > max_recv) + throw new IOException("Unexpected fragment length: " + length); + + while (off < length) { + off += in.readDirect(buf, off, length - off); + } + } + public void close() throws IOException { + state = 0; + if (out != null) + out.close(); + } +} + diff --git a/src/jcifs/dcerpc/DcerpcSecurityProvider.java b/src/jcifs/dcerpc/DcerpcSecurityProvider.java new file mode 100644 index 0000000..0b3d2a6 --- /dev/null +++ b/src/jcifs/dcerpc/DcerpcSecurityProvider.java @@ -0,0 +1,27 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2009 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +import jcifs.dcerpc.ndr.NdrBuffer; + +public interface DcerpcSecurityProvider +{ + void wrap(NdrBuffer outgoing) throws DcerpcException; + void unwrap(NdrBuffer incoming) throws DcerpcException; +} diff --git a/src/jcifs/dcerpc/UUID.java b/src/jcifs/dcerpc/UUID.java new file mode 100644 index 0000000..77b7fb5 --- /dev/null +++ b/src/jcifs/dcerpc/UUID.java @@ -0,0 +1,110 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +import jcifs.util.*; + +public class UUID extends rpc.uuid_t { + + public static int hex_to_bin(char[] arr, int offset, int length) { + int value = 0; + int ai, count; + + count = 0; + for (ai = offset; ai < arr.length && count < length; ai++) { + value <<= 4; + switch (arr[ai]) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + value += arr[ai] - '0'; + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + value += 10 + (arr[ai] - 'A'); + break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + value += 10 + (arr[ai] - 'a'); + break; + default: + throw new IllegalArgumentException(new String(arr, offset, length)); + } + count++; + } + + return value; + } + static final char[] HEXCHARS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + public static String bin_to_hex(int value, int length) { + char[] arr = new char[length]; + int ai = arr.length; + while (ai-- > 0) { + arr[ai] = HEXCHARS[value & 0xF]; + value >>>= 4; + } + return new String(arr); + } + private static byte B(int i) { return (byte)(i & 0xFF); } + private static short S(int i) { return (short)(i & 0xFFFF); } + + public UUID(rpc.uuid_t uuid) { + time_low = uuid.time_low; + time_mid = uuid.time_mid; + time_hi_and_version = uuid.time_hi_and_version; + clock_seq_hi_and_reserved = uuid.clock_seq_hi_and_reserved; + clock_seq_low = uuid.clock_seq_low; + node = new byte[6]; + node[0] = uuid.node[0]; + node[1] = uuid.node[1]; + node[2] = uuid.node[2]; + node[3] = uuid.node[3]; + node[4] = uuid.node[4]; + node[5] = uuid.node[5]; + } + public UUID(String str) { + char[] arr = str.toCharArray(); + time_low = hex_to_bin(arr, 0, 8); + time_mid = S(hex_to_bin(arr, 9, 4)); + time_hi_and_version = S(hex_to_bin(arr, 14, 4)); + clock_seq_hi_and_reserved = B(hex_to_bin(arr, 19, 2)); + clock_seq_low = B(hex_to_bin(arr, 21, 2)); + node = new byte[6]; + node[0] = B(hex_to_bin(arr, 24, 2)); + node[1] = B(hex_to_bin(arr, 26, 2)); + node[2] = B(hex_to_bin(arr, 28, 2)); + node[3] = B(hex_to_bin(arr, 30, 2)); + node[4] = B(hex_to_bin(arr, 32, 2)); + node[5] = B(hex_to_bin(arr, 34, 2)); + } + + public String toString() { + return bin_to_hex(time_low, 8) + '-' + + bin_to_hex(time_mid, 4) + '-' + + bin_to_hex(time_hi_and_version, 4) + '-' + + bin_to_hex(clock_seq_hi_and_reserved, 2) + + bin_to_hex(clock_seq_low, 2) + '-' + + bin_to_hex(node[0], 2) + + bin_to_hex(node[1], 2) + + bin_to_hex(node[2], 2) + + bin_to_hex(node[3], 2) + + bin_to_hex(node[4], 2) + + bin_to_hex(node[5], 2); + } +} diff --git a/src/jcifs/dcerpc/UnicodeString.java b/src/jcifs/dcerpc/UnicodeString.java new file mode 100644 index 0000000..0417bac --- /dev/null +++ b/src/jcifs/dcerpc/UnicodeString.java @@ -0,0 +1,62 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc; + +public class UnicodeString extends rpc.unicode_string { + + boolean zterm; + + public UnicodeString(boolean zterm) { + this.zterm = zterm; + } + public UnicodeString(rpc.unicode_string rus, boolean zterm) { + this.length = rus.length; + this.maximum_length = rus.maximum_length; + this.buffer = rus.buffer; + this.zterm = zterm; + } + + public UnicodeString(String str, boolean zterm) { + this.zterm = zterm; + + int len = str.length(); + int zt = zterm ? 1 : 0; + + length = maximum_length = (short)((len + zt) * 2); + buffer = new short[len + zt]; + + int i; + for (i = 0; i < len; i++) { + buffer[i] = (short)str.charAt(i); + } + if (zterm) { + buffer[i] = (short)0; + } + } + + public String toString() { + int len = length / 2 - (zterm ? 1 : 0); + char[] ca = new char[len]; + for (int i = 0; i < len; i++) { + ca[i] = (char)buffer[i]; + } + return new String(ca, 0, len); + } +} diff --git a/src/jcifs/dcerpc/msrpc/LsaPolicyHandle.java b/src/jcifs/dcerpc/msrpc/LsaPolicyHandle.java new file mode 100644 index 0000000..8fa91d1 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/LsaPolicyHandle.java @@ -0,0 +1,42 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import java.io.IOException; + +import jcifs.smb.SmbException; + +import jcifs.dcerpc.*; + +public class LsaPolicyHandle extends rpc.policy_handle { + + public LsaPolicyHandle(DcerpcHandle handle, String server, int access) throws IOException { + if (server == null) + server = "\\\\"; + MsrpcLsarOpenPolicy2 rpc = new MsrpcLsarOpenPolicy2(server, access, this); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + } + + public void close() throws IOException { + } +} + diff --git a/src/jcifs/dcerpc/msrpc/LsarSidArrayX.java b/src/jcifs/dcerpc/msrpc/LsarSidArrayX.java new file mode 100644 index 0000000..061345b --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/LsarSidArrayX.java @@ -0,0 +1,15 @@ +package jcifs.dcerpc.msrpc; + +import jcifs.smb.SID; + +class LsarSidArrayX extends lsarpc.LsarSidArray { + + LsarSidArrayX(SID[] sids) { + this.num_sids = sids.length; + this.sids = new lsarpc.LsarSidPtr[sids.length]; + for (int si = 0; si < sids.length; si++) { + this.sids[si] = new lsarpc.LsarSidPtr(); + this.sids[si].sid = sids[si]; + } + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcDfsRootEnum.java b/src/jcifs/dcerpc/msrpc/MsrpcDfsRootEnum.java new file mode 100644 index 0000000..fb7487a --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcDfsRootEnum.java @@ -0,0 +1,42 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2008 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import jcifs.smb.*; +import jcifs.dcerpc.ndr.*; + +public class MsrpcDfsRootEnum extends netdfs.NetrDfsEnumEx { + + public MsrpcDfsRootEnum(String server) { + super(server, 200, 0xFFFF, new netdfs.DfsEnumStruct(), new NdrLong(0)); + info.level = level; + info.e = new netdfs.DfsEnumArray200(); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } + + public FileEntry[] getEntries() { + netdfs.DfsEnumArray200 a200 = (netdfs.DfsEnumArray200)info.e; + SmbShareInfo[] entries = new SmbShareInfo[a200.count]; + for (int i = 0; i < a200.count; i++) { + entries[i] = new SmbShareInfo(a200.s[i].dfs_name, 0, null); + } + return entries; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcEnumerateAliasesInDomain.java b/src/jcifs/dcerpc/msrpc/MsrpcEnumerateAliasesInDomain.java new file mode 100644 index 0000000..6e2c5d4 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcEnumerateAliasesInDomain.java @@ -0,0 +1,34 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import jcifs.smb.*; +import jcifs.dcerpc.*; + +public class MsrpcEnumerateAliasesInDomain extends samr.SamrEnumerateAliasesInDomain { + + public MsrpcEnumerateAliasesInDomain(SamrDomainHandle domainHandle, + int acct_flags, + samr.SamrSamArray sam) { + super(domainHandle, 0, acct_flags, null, 0); + this.sam = sam; + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcGetMembersInAlias.java b/src/jcifs/dcerpc/msrpc/MsrpcGetMembersInAlias.java new file mode 100644 index 0000000..ad12780 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcGetMembersInAlias.java @@ -0,0 +1,32 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import jcifs.smb.*; +import jcifs.dcerpc.*; + +public class MsrpcGetMembersInAlias extends samr.SamrGetMembersInAlias { + + public MsrpcGetMembersInAlias(SamrAliasHandle aliasHandle, lsarpc.LsarSidArray sids) { + super(aliasHandle, sids); + this.sids = sids; + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcLookupSids.java b/src/jcifs/dcerpc/msrpc/MsrpcLookupSids.java new file mode 100644 index 0000000..9308385 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcLookupSids.java @@ -0,0 +1,41 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import jcifs.smb.*; +import jcifs.util.Hexdump; +import jcifs.dcerpc.*; + +public class MsrpcLookupSids extends lsarpc.LsarLookupSids { + + SID[] sids; + + public MsrpcLookupSids(LsaPolicyHandle policyHandle, SID[] sids) { + super(policyHandle, + new LsarSidArrayX(sids), + new lsarpc.LsarRefDomainList(), + new lsarpc.LsarTransNameArray(), + (short)1, + sids.length); + this.sids = sids; + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcLsarOpenPolicy2.java b/src/jcifs/dcerpc/msrpc/MsrpcLsarOpenPolicy2.java new file mode 100644 index 0000000..cb03253 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcLsarOpenPolicy2.java @@ -0,0 +1,36 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +public class MsrpcLsarOpenPolicy2 extends lsarpc.LsarOpenPolicy2 { + + public MsrpcLsarOpenPolicy2(String server, int access, LsaPolicyHandle policyHandle) { + super(server, new lsarpc.LsarObjectAttributes(), access, policyHandle); + object_attributes.length = 24; +lsarpc.LsarQosInfo qos = new lsarpc.LsarQosInfo(); +qos.length = 12; +qos.impersonation_level = 2; +qos.context_mode = 1; +qos.effective_only = 0; +object_attributes.security_quality_of_service = qos; + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcQueryInformationPolicy.java b/src/jcifs/dcerpc/msrpc/MsrpcQueryInformationPolicy.java new file mode 100644 index 0000000..855ed2c --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcQueryInformationPolicy.java @@ -0,0 +1,34 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import jcifs.smb.*; +import jcifs.dcerpc.*; +import jcifs.dcerpc.ndr.*; + +public class MsrpcQueryInformationPolicy extends lsarpc.LsarQueryInformationPolicy { + + public MsrpcQueryInformationPolicy(LsaPolicyHandle policyHandle, + short level, + NdrObject info) { + super(policyHandle, level, info); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcSamrConnect2.java b/src/jcifs/dcerpc/msrpc/MsrpcSamrConnect2.java new file mode 100644 index 0000000..d7b99e6 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcSamrConnect2.java @@ -0,0 +1,28 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +public class MsrpcSamrConnect2 extends samr.SamrConnect2 { + + public MsrpcSamrConnect2(String server, int access, SamrPolicyHandle policyHandle) { + super(server, access, policyHandle); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcSamrConnect4.java b/src/jcifs/dcerpc/msrpc/MsrpcSamrConnect4.java new file mode 100644 index 0000000..9ba6b8f --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcSamrConnect4.java @@ -0,0 +1,28 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +public class MsrpcSamrConnect4 extends samr.SamrConnect4 { + + public MsrpcSamrConnect4(String server, int access, SamrPolicyHandle policyHandle) { + super(server, 2, access, policyHandle); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenAlias.java b/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenAlias.java new file mode 100644 index 0000000..a323caa --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenAlias.java @@ -0,0 +1,33 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import jcifs.dcerpc.*; + +public class MsrpcSamrOpenAlias extends samr.SamrOpenAlias { + + public MsrpcSamrOpenAlias(SamrDomainHandle handle, + int access, + int rid, + SamrAliasHandle aliasHandle) { + super(handle, access, rid, aliasHandle); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenDomain.java b/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenDomain.java new file mode 100644 index 0000000..6350b0e --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenDomain.java @@ -0,0 +1,33 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import jcifs.dcerpc.*; + +public class MsrpcSamrOpenDomain extends samr.SamrOpenDomain { + + public MsrpcSamrOpenDomain(SamrPolicyHandle handle, + int access, + rpc.sid_t sid, + SamrDomainHandle domainHandle) { + super(handle, access, sid, domainHandle); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcShareEnum.java b/src/jcifs/dcerpc/msrpc/MsrpcShareEnum.java new file mode 100644 index 0000000..6862059 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcShareEnum.java @@ -0,0 +1,54 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import jcifs.smb.*; +import jcifs.util.Hexdump; + +public class MsrpcShareEnum extends srvsvc.ShareEnumAll { + + class MsrpcShareInfo1 extends SmbShareInfo { + + MsrpcShareInfo1(srvsvc.ShareInfo1 info1) { + this.netName = info1.netname; + this.type = info1.type; + this.remark = info1.remark; + } + } + + public MsrpcShareEnum(String server) { + super("\\\\" + server, 1, new srvsvc.ShareInfoCtr1(), -1, 0, 0); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } + + public FileEntry[] getEntries() { + /* The ShareInfo1 class does not implement the FileEntry + * interface (because it is generated from IDL). Therefore + * we must create an array of objects that do. + */ + srvsvc.ShareInfoCtr1 ctr = (srvsvc.ShareInfoCtr1)info; + MsrpcShareInfo1[] entries = new MsrpcShareInfo1[ctr.count]; + for (int i = 0; i < ctr.count; i++) { + entries[i] = new MsrpcShareInfo1(ctr.array[i]); + } + return entries; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcShareGetInfo.java b/src/jcifs/dcerpc/msrpc/MsrpcShareGetInfo.java new file mode 100644 index 0000000..035d65c --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcShareGetInfo.java @@ -0,0 +1,44 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import java.io.IOException; + +import jcifs.smb.*; +import jcifs.util.Hexdump; + +public class MsrpcShareGetInfo extends srvsvc.ShareGetInfo { + + public MsrpcShareGetInfo(String server, String sharename) { + super(server, sharename, 502, new srvsvc.ShareInfo502()); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } + + public ACE[] getSecurity() throws IOException { + srvsvc.ShareInfo502 info502 = (srvsvc.ShareInfo502)info; + if (info502.security_descriptor != null) { + SecurityDescriptor sd; + sd = new SecurityDescriptor(info502.security_descriptor, 0, info502.sd_size); + return sd.aces; + } + return null; + } +} diff --git a/src/jcifs/dcerpc/msrpc/SamrAliasHandle.java b/src/jcifs/dcerpc/msrpc/SamrAliasHandle.java new file mode 100644 index 0000000..7b3ab22 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/SamrAliasHandle.java @@ -0,0 +1,42 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import java.io.IOException; + +import jcifs.smb.SmbException; + +import jcifs.dcerpc.*; + +public class SamrAliasHandle extends rpc.policy_handle { + + public SamrAliasHandle(DcerpcHandle handle, + SamrDomainHandle domainHandle, + int access, + int rid) throws IOException { + MsrpcSamrOpenAlias rpc = new MsrpcSamrOpenAlias(domainHandle, access, rid, this); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + } + + public void close() throws IOException { + } +} + diff --git a/src/jcifs/dcerpc/msrpc/SamrDomainHandle.java b/src/jcifs/dcerpc/msrpc/SamrDomainHandle.java new file mode 100644 index 0000000..0b4e83c --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/SamrDomainHandle.java @@ -0,0 +1,42 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import java.io.IOException; + +import jcifs.smb.SmbException; + +import jcifs.dcerpc.*; + +public class SamrDomainHandle extends rpc.policy_handle { + + public SamrDomainHandle(DcerpcHandle handle, + SamrPolicyHandle policyHandle, + int access, + rpc.sid_t sid) throws IOException { + MsrpcSamrOpenDomain rpc = new MsrpcSamrOpenDomain(policyHandle, access, sid, this); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + } + + public void close() throws IOException { + } +} + diff --git a/src/jcifs/dcerpc/msrpc/SamrPolicyHandle.java b/src/jcifs/dcerpc/msrpc/SamrPolicyHandle.java new file mode 100644 index 0000000..7a01c55 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/SamrPolicyHandle.java @@ -0,0 +1,45 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.msrpc; + +import java.io.IOException; + +import jcifs.dcerpc.*; + +public class SamrPolicyHandle extends rpc.policy_handle { + + public SamrPolicyHandle(DcerpcHandle handle, String server, int access) throws IOException { + if (server == null) + server = "\\\\"; + MsrpcSamrConnect4 rpc = new MsrpcSamrConnect4(server, access, this); + try { + handle.sendrecv(rpc); + } catch (DcerpcException de) { + if (de.getErrorCode() != DcerpcError.DCERPC_FAULT_OP_RNG_ERROR) + throw de; + + MsrpcSamrConnect2 rpc2 = new MsrpcSamrConnect2(server, access, this); + handle.sendrecv(rpc2); + } + } + + public void close() throws IOException { + } +} + diff --git a/src/jcifs/dcerpc/msrpc/lsarpc.idl b/src/jcifs/dcerpc/msrpc/lsarpc.idl new file mode 100644 index 0000000..1cfa764 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/lsarpc.idl @@ -0,0 +1,132 @@ +[ + uuid(12345778-1234-abcd-ef00-0123456789ab), + version(0.0) +] +interface lsarpc +{ + import "../rpc.idl"; + + typedef struct { + uint32_t length; + uint16_t impersonation_level; + uint8_t context_mode; + uint8_t effective_only; + } LsarQosInfo; + + typedef struct { + uint32_t length; + uint8_t *root_directory; + unicode_string *object_name; + uint32_t attributes; + uint32_t security_descriptor; + LsarQosInfo *security_quality_of_service; + } LsarObjectAttributes; + + typedef struct { + unicode_string name; + sid_t *sid; + } LsarDomainInfo; + + typedef struct { + unicode_string name; + unicode_string dns_domain; + unicode_string dns_forest; + uuid_t domain_guid; + sid_t *sid; + } LsarDnsDomainInfo; + + enum { + POLICY_INFO_AUDIT_EVENTS = 2, + POLICY_INFO_PRIMARY_DOMAIN = 3, + POLICY_INFO_ACCOUNT_DOMAIN = 5, + POLICY_INFO_SERVER_ROLE = 6, + POLICY_INFO_MODIFICATION = 9, + POLICY_INFO_DNS_DOMAIN = 12 + }; + + typedef [switch_type(short)] union { + [case(POLICY_INFO_ACCOUNT_DOMAIN)] LsarDomainInfo account_domain; + [case(POLICY_INFO_DNS_DOMAIN)] LsarDnsDomainInfo dns_domain; + } LsarPolicyInfo; + + typedef struct { + sid_t *sid; + } LsarSidPtr; + + typedef struct { + [range(0,1000)] uint32_t num_sids; + [size_is(num_sids)] LsarSidPtr *sids; + } LsarSidArray; + + typedef enum { + SID_NAME_USE_NONE = 0, /* NOTUSED */ + SID_NAME_USER = 1, /* user */ + SID_NAME_DOM_GRP = 2, /* domain group */ + SID_NAME_DOMAIN = 3, /* domain: don't know what this is */ + SID_NAME_ALIAS = 4, /* local group */ + SID_NAME_WKN_GRP = 5, /* well-known group */ + SID_NAME_DELETED = 6, /* deleted account: needed for c2 rating */ + SID_NAME_INVALID = 7, /* invalid account */ + SID_NAME_UNKNOWN = 8 /* oops. */ + } LsarSidType; + + typedef struct { + LsarSidType sid_type; + uint32_t rid; + uint32_t sid_index; + } LsarTranslatedSid; + + typedef struct { + [range(0,1000)] uint32_t count; + [size_is(count)] LsarTranslatedSid *sids; + } LsarTransSidArray; + + typedef struct { + unicode_string name; + sid_t *sid; + } LsarTrustInformation; + + typedef struct { + [range(0,1000)] uint32_t count; + [size_is(count)] LsarTrustInformation *domains; + uint32_t max_count; + } LsarRefDomainList; + + typedef struct { + uint16_t sid_type; + unicode_string name; + uint32_t sid_index; + } LsarTranslatedName; + + typedef struct { + [range(0,1000)] uint32_t count; + [size_is(count)] LsarTranslatedName *names; + } LsarTransNameArray; + + [op(0x00)] + int LsarClose([in,out] policy_handle *handle); + + [op(0x07)] + int LsarQueryInformationPolicy([in] policy_handle *handle, + [in] uint16_t level, + [out,switch_is(level),unique] LsarPolicyInfo *info); + + [op(0x0f)] + int LsarLookupSids([in] policy_handle *handle, + [in] LsarSidArray *sids, + [out,unique] LsarRefDomainList *domains, + [in,out] LsarTransNameArray *names, + [in] uint16_t level, + [in,out] uint32_t *count); + + [op(0x2c)] + int LsarOpenPolicy2([in,string,unique] wchar_t *system_name, + [in] LsarObjectAttributes *object_attributes, + [in] uint32_t desired_access, + [out] policy_handle *policy_handle); + + [op(0x2e)] + int LsarQueryInformationPolicy2([in] policy_handle *handle, + [in] uint16_t level, + [out,switch_is(level),unique] LsarPolicyInfo *info); +} diff --git a/src/jcifs/dcerpc/msrpc/lsarpc.java b/src/jcifs/dcerpc/msrpc/lsarpc.java new file mode 100644 index 0000000..87a922a --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/lsarpc.java @@ -0,0 +1,914 @@ +package jcifs.dcerpc.msrpc; + +import jcifs.dcerpc.*; +import jcifs.dcerpc.ndr.*; + +public class lsarpc { + + public static String getSyntax() { + return "12345778-1234-abcd-ef00-0123456789ab:0.0"; + } + + public static class LsarQosInfo extends NdrObject { + + public int length; + public short impersonation_level; + public byte context_mode; + public byte effective_only; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(length); + _dst.enc_ndr_short(impersonation_level); + _dst.enc_ndr_small(context_mode); + _dst.enc_ndr_small(effective_only); + + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + length = (int)_src.dec_ndr_long(); + impersonation_level = (short)_src.dec_ndr_short(); + context_mode = (byte)_src.dec_ndr_small(); + effective_only = (byte)_src.dec_ndr_small(); + + } + } + public static class LsarObjectAttributes extends NdrObject { + + public int length; + public NdrSmall root_directory; + public rpc.unicode_string object_name; + public int attributes; + public int security_descriptor; + public LsarQosInfo security_quality_of_service; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(length); + _dst.enc_ndr_referent(root_directory, 1); + _dst.enc_ndr_referent(object_name, 1); + _dst.enc_ndr_long(attributes); + _dst.enc_ndr_long(security_descriptor); + _dst.enc_ndr_referent(security_quality_of_service, 1); + + if (root_directory != null) { + _dst = _dst.deferred; + root_directory.encode(_dst); + + } + if (object_name != null) { + _dst = _dst.deferred; + object_name.encode(_dst); + + } + if (security_quality_of_service != null) { + _dst = _dst.deferred; + security_quality_of_service.encode(_dst); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + length = (int)_src.dec_ndr_long(); + int _root_directoryp = _src.dec_ndr_long(); + int _object_namep = _src.dec_ndr_long(); + attributes = (int)_src.dec_ndr_long(); + security_descriptor = (int)_src.dec_ndr_long(); + int _security_quality_of_servicep = _src.dec_ndr_long(); + + if (_root_directoryp != 0) { + _src = _src.deferred; + root_directory.decode(_src); + + } + if (_object_namep != 0) { + if (object_name == null) { /* YOYOYO */ + object_name = new rpc.unicode_string(); + } + _src = _src.deferred; + object_name.decode(_src); + + } + if (_security_quality_of_servicep != 0) { + if (security_quality_of_service == null) { /* YOYOYO */ + security_quality_of_service = new LsarQosInfo(); + } + _src = _src.deferred; + security_quality_of_service.decode(_src); + + } + } + } + public static class LsarDomainInfo extends NdrObject { + + public rpc.unicode_string name; + public rpc.sid_t sid; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_short(name.length); + _dst.enc_ndr_short(name.maximum_length); + _dst.enc_ndr_referent(name.buffer, 1); + _dst.enc_ndr_referent(sid, 1); + + if (name.buffer != null) { + _dst = _dst.deferred; + int _name_bufferl = name.length / 2; + int _name_buffers = name.maximum_length / 2; + _dst.enc_ndr_long(_name_buffers); + _dst.enc_ndr_long(0); + _dst.enc_ndr_long(_name_bufferl); + int _name_bufferi = _dst.index; + _dst.advance(2 * _name_bufferl); + + _dst = _dst.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + _dst.enc_ndr_short(name.buffer[_i]); + } + } + if (sid != null) { + _dst = _dst.deferred; + sid.encode(_dst); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + _src.align(4); + if (name == null) { + name = new rpc.unicode_string(); + } + name.length = (short)_src.dec_ndr_short(); + name.maximum_length = (short)_src.dec_ndr_short(); + int _name_bufferp = _src.dec_ndr_long(); + int _sidp = _src.dec_ndr_long(); + + if (_name_bufferp != 0) { + _src = _src.deferred; + int _name_buffers = _src.dec_ndr_long(); + _src.dec_ndr_long(); + int _name_bufferl = _src.dec_ndr_long(); + int _name_bufferi = _src.index; + _src.advance(2 * _name_bufferl); + + if (name.buffer == null) { + if (_name_buffers < 0 || _name_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + name.buffer = new short[_name_buffers]; + } + _src = _src.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + name.buffer[_i] = (short)_src.dec_ndr_short(); + } + } + if (_sidp != 0) { + if (sid == null) { /* YOYOYO */ + sid = new rpc.sid_t(); + } + _src = _src.deferred; + sid.decode(_src); + + } + } + } + public static class LsarDnsDomainInfo extends NdrObject { + + public rpc.unicode_string name; + public rpc.unicode_string dns_domain; + public rpc.unicode_string dns_forest; + public rpc.uuid_t domain_guid; + public rpc.sid_t sid; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_short(name.length); + _dst.enc_ndr_short(name.maximum_length); + _dst.enc_ndr_referent(name.buffer, 1); + _dst.enc_ndr_short(dns_domain.length); + _dst.enc_ndr_short(dns_domain.maximum_length); + _dst.enc_ndr_referent(dns_domain.buffer, 1); + _dst.enc_ndr_short(dns_forest.length); + _dst.enc_ndr_short(dns_forest.maximum_length); + _dst.enc_ndr_referent(dns_forest.buffer, 1); + _dst.enc_ndr_long(domain_guid.time_low); + _dst.enc_ndr_short(domain_guid.time_mid); + _dst.enc_ndr_short(domain_guid.time_hi_and_version); + _dst.enc_ndr_small(domain_guid.clock_seq_hi_and_reserved); + _dst.enc_ndr_small(domain_guid.clock_seq_low); + int _domain_guid_nodes = 6; + int _domain_guid_nodei = _dst.index; + _dst.advance(1 * _domain_guid_nodes); + _dst.enc_ndr_referent(sid, 1); + + if (name.buffer != null) { + _dst = _dst.deferred; + int _name_bufferl = name.length / 2; + int _name_buffers = name.maximum_length / 2; + _dst.enc_ndr_long(_name_buffers); + _dst.enc_ndr_long(0); + _dst.enc_ndr_long(_name_bufferl); + int _name_bufferi = _dst.index; + _dst.advance(2 * _name_bufferl); + + _dst = _dst.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + _dst.enc_ndr_short(name.buffer[_i]); + } + } + if (dns_domain.buffer != null) { + _dst = _dst.deferred; + int _dns_domain_bufferl = dns_domain.length / 2; + int _dns_domain_buffers = dns_domain.maximum_length / 2; + _dst.enc_ndr_long(_dns_domain_buffers); + _dst.enc_ndr_long(0); + _dst.enc_ndr_long(_dns_domain_bufferl); + int _dns_domain_bufferi = _dst.index; + _dst.advance(2 * _dns_domain_bufferl); + + _dst = _dst.derive(_dns_domain_bufferi); + for (int _i = 0; _i < _dns_domain_bufferl; _i++) { + _dst.enc_ndr_short(dns_domain.buffer[_i]); + } + } + if (dns_forest.buffer != null) { + _dst = _dst.deferred; + int _dns_forest_bufferl = dns_forest.length / 2; + int _dns_forest_buffers = dns_forest.maximum_length / 2; + _dst.enc_ndr_long(_dns_forest_buffers); + _dst.enc_ndr_long(0); + _dst.enc_ndr_long(_dns_forest_bufferl); + int _dns_forest_bufferi = _dst.index; + _dst.advance(2 * _dns_forest_bufferl); + + _dst = _dst.derive(_dns_forest_bufferi); + for (int _i = 0; _i < _dns_forest_bufferl; _i++) { + _dst.enc_ndr_short(dns_forest.buffer[_i]); + } + } + _dst = _dst.derive(_domain_guid_nodei); + for (int _i = 0; _i < _domain_guid_nodes; _i++) { + _dst.enc_ndr_small(domain_guid.node[_i]); + } + if (sid != null) { + _dst = _dst.deferred; + sid.encode(_dst); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + _src.align(4); + if (name == null) { + name = new rpc.unicode_string(); + } + name.length = (short)_src.dec_ndr_short(); + name.maximum_length = (short)_src.dec_ndr_short(); + int _name_bufferp = _src.dec_ndr_long(); + _src.align(4); + if (dns_domain == null) { + dns_domain = new rpc.unicode_string(); + } + dns_domain.length = (short)_src.dec_ndr_short(); + dns_domain.maximum_length = (short)_src.dec_ndr_short(); + int _dns_domain_bufferp = _src.dec_ndr_long(); + _src.align(4); + if (dns_forest == null) { + dns_forest = new rpc.unicode_string(); + } + dns_forest.length = (short)_src.dec_ndr_short(); + dns_forest.maximum_length = (short)_src.dec_ndr_short(); + int _dns_forest_bufferp = _src.dec_ndr_long(); + _src.align(4); + if (domain_guid == null) { + domain_guid = new rpc.uuid_t(); + } + domain_guid.time_low = (int)_src.dec_ndr_long(); + domain_guid.time_mid = (short)_src.dec_ndr_short(); + domain_guid.time_hi_and_version = (short)_src.dec_ndr_short(); + domain_guid.clock_seq_hi_and_reserved = (byte)_src.dec_ndr_small(); + domain_guid.clock_seq_low = (byte)_src.dec_ndr_small(); + int _domain_guid_nodes = 6; + int _domain_guid_nodei = _src.index; + _src.advance(1 * _domain_guid_nodes); + int _sidp = _src.dec_ndr_long(); + + if (_name_bufferp != 0) { + _src = _src.deferred; + int _name_buffers = _src.dec_ndr_long(); + _src.dec_ndr_long(); + int _name_bufferl = _src.dec_ndr_long(); + int _name_bufferi = _src.index; + _src.advance(2 * _name_bufferl); + + if (name.buffer == null) { + if (_name_buffers < 0 || _name_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + name.buffer = new short[_name_buffers]; + } + _src = _src.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + name.buffer[_i] = (short)_src.dec_ndr_short(); + } + } + if (_dns_domain_bufferp != 0) { + _src = _src.deferred; + int _dns_domain_buffers = _src.dec_ndr_long(); + _src.dec_ndr_long(); + int _dns_domain_bufferl = _src.dec_ndr_long(); + int _dns_domain_bufferi = _src.index; + _src.advance(2 * _dns_domain_bufferl); + + if (dns_domain.buffer == null) { + if (_dns_domain_buffers < 0 || _dns_domain_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + dns_domain.buffer = new short[_dns_domain_buffers]; + } + _src = _src.derive(_dns_domain_bufferi); + for (int _i = 0; _i < _dns_domain_bufferl; _i++) { + dns_domain.buffer[_i] = (short)_src.dec_ndr_short(); + } + } + if (_dns_forest_bufferp != 0) { + _src = _src.deferred; + int _dns_forest_buffers = _src.dec_ndr_long(); + _src.dec_ndr_long(); + int _dns_forest_bufferl = _src.dec_ndr_long(); + int _dns_forest_bufferi = _src.index; + _src.advance(2 * _dns_forest_bufferl); + + if (dns_forest.buffer == null) { + if (_dns_forest_buffers < 0 || _dns_forest_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + dns_forest.buffer = new short[_dns_forest_buffers]; + } + _src = _src.derive(_dns_forest_bufferi); + for (int _i = 0; _i < _dns_forest_bufferl; _i++) { + dns_forest.buffer[_i] = (short)_src.dec_ndr_short(); + } + } + if (domain_guid.node == null) { + if (_domain_guid_nodes < 0 || _domain_guid_nodes > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + domain_guid.node = new byte[_domain_guid_nodes]; + } + _src = _src.derive(_domain_guid_nodei); + for (int _i = 0; _i < _domain_guid_nodes; _i++) { + domain_guid.node[_i] = (byte)_src.dec_ndr_small(); + } + if (_sidp != 0) { + if (sid == null) { /* YOYOYO */ + sid = new rpc.sid_t(); + } + _src = _src.deferred; + sid.decode(_src); + + } + } + } + public static final int POLICY_INFO_AUDIT_EVENTS = 2; + public static final int POLICY_INFO_PRIMARY_DOMAIN = 3; + public static final int POLICY_INFO_ACCOUNT_DOMAIN = 5; + public static final int POLICY_INFO_SERVER_ROLE = 6; + public static final int POLICY_INFO_MODIFICATION = 9; + public static final int POLICY_INFO_DNS_DOMAIN = 12; + + public static class LsarSidPtr extends NdrObject { + + public rpc.sid_t sid; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_referent(sid, 1); + + if (sid != null) { + _dst = _dst.deferred; + sid.encode(_dst); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + int _sidp = _src.dec_ndr_long(); + + if (_sidp != 0) { + if (sid == null) { /* YOYOYO */ + sid = new rpc.sid_t(); + } + _src = _src.deferred; + sid.decode(_src); + + } + } + } + public static class LsarSidArray extends NdrObject { + + public int num_sids; + public LsarSidPtr[] sids; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(num_sids); + _dst.enc_ndr_referent(sids, 1); + + if (sids != null) { + _dst = _dst.deferred; + int _sidss = num_sids; + _dst.enc_ndr_long(_sidss); + int _sidsi = _dst.index; + _dst.advance(4 * _sidss); + + _dst = _dst.derive(_sidsi); + for (int _i = 0; _i < _sidss; _i++) { + sids[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + num_sids = (int)_src.dec_ndr_long(); + int _sidsp = _src.dec_ndr_long(); + + if (_sidsp != 0) { + _src = _src.deferred; + int _sidss = _src.dec_ndr_long(); + int _sidsi = _src.index; + _src.advance(4 * _sidss); + + if (sids == null) { + if (_sidss < 0 || _sidss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + sids = new LsarSidPtr[_sidss]; + } + _src = _src.derive(_sidsi); + for (int _i = 0; _i < _sidss; _i++) { + if (sids[_i] == null) { + sids[_i] = new LsarSidPtr(); + } + sids[_i].decode(_src); + } + } + } + } + public static final int SID_NAME_USE_NONE = 0; + public static final int SID_NAME_USER = 1; + public static final int SID_NAME_DOM_GRP = 2; + public static final int SID_NAME_DOMAIN = 3; + public static final int SID_NAME_ALIAS = 4; + public static final int SID_NAME_WKN_GRP = 5; + public static final int SID_NAME_DELETED = 6; + public static final int SID_NAME_INVALID = 7; + public static final int SID_NAME_UNKNOWN = 8; + + public static class LsarTranslatedSid extends NdrObject { + + public int sid_type; + public int rid; + public int sid_index; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_short(sid_type); + _dst.enc_ndr_long(rid); + _dst.enc_ndr_long(sid_index); + + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + sid_type = (int)_src.dec_ndr_short(); + rid = (int)_src.dec_ndr_long(); + sid_index = (int)_src.dec_ndr_long(); + + } + } + public static class LsarTransSidArray extends NdrObject { + + public int count; + public LsarTranslatedSid[] sids; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(sids, 1); + + if (sids != null) { + _dst = _dst.deferred; + int _sidss = count; + _dst.enc_ndr_long(_sidss); + int _sidsi = _dst.index; + _dst.advance(12 * _sidss); + + _dst = _dst.derive(_sidsi); + for (int _i = 0; _i < _sidss; _i++) { + sids[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _sidsp = _src.dec_ndr_long(); + + if (_sidsp != 0) { + _src = _src.deferred; + int _sidss = _src.dec_ndr_long(); + int _sidsi = _src.index; + _src.advance(12 * _sidss); + + if (sids == null) { + if (_sidss < 0 || _sidss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + sids = new LsarTranslatedSid[_sidss]; + } + _src = _src.derive(_sidsi); + for (int _i = 0; _i < _sidss; _i++) { + if (sids[_i] == null) { + sids[_i] = new LsarTranslatedSid(); + } + sids[_i].decode(_src); + } + } + } + } + public static class LsarTrustInformation extends NdrObject { + + public rpc.unicode_string name; + public rpc.sid_t sid; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_short(name.length); + _dst.enc_ndr_short(name.maximum_length); + _dst.enc_ndr_referent(name.buffer, 1); + _dst.enc_ndr_referent(sid, 1); + + if (name.buffer != null) { + _dst = _dst.deferred; + int _name_bufferl = name.length / 2; + int _name_buffers = name.maximum_length / 2; + _dst.enc_ndr_long(_name_buffers); + _dst.enc_ndr_long(0); + _dst.enc_ndr_long(_name_bufferl); + int _name_bufferi = _dst.index; + _dst.advance(2 * _name_bufferl); + + _dst = _dst.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + _dst.enc_ndr_short(name.buffer[_i]); + } + } + if (sid != null) { + _dst = _dst.deferred; + sid.encode(_dst); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + _src.align(4); + if (name == null) { + name = new rpc.unicode_string(); + } + name.length = (short)_src.dec_ndr_short(); + name.maximum_length = (short)_src.dec_ndr_short(); + int _name_bufferp = _src.dec_ndr_long(); + int _sidp = _src.dec_ndr_long(); + + if (_name_bufferp != 0) { + _src = _src.deferred; + int _name_buffers = _src.dec_ndr_long(); + _src.dec_ndr_long(); + int _name_bufferl = _src.dec_ndr_long(); + int _name_bufferi = _src.index; + _src.advance(2 * _name_bufferl); + + if (name.buffer == null) { + if (_name_buffers < 0 || _name_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + name.buffer = new short[_name_buffers]; + } + _src = _src.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + name.buffer[_i] = (short)_src.dec_ndr_short(); + } + } + if (_sidp != 0) { + if (sid == null) { /* YOYOYO */ + sid = new rpc.sid_t(); + } + _src = _src.deferred; + sid.decode(_src); + + } + } + } + public static class LsarRefDomainList extends NdrObject { + + public int count; + public LsarTrustInformation[] domains; + public int max_count; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(domains, 1); + _dst.enc_ndr_long(max_count); + + if (domains != null) { + _dst = _dst.deferred; + int _domainss = count; + _dst.enc_ndr_long(_domainss); + int _domainsi = _dst.index; + _dst.advance(12 * _domainss); + + _dst = _dst.derive(_domainsi); + for (int _i = 0; _i < _domainss; _i++) { + domains[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _domainsp = _src.dec_ndr_long(); + max_count = (int)_src.dec_ndr_long(); + + if (_domainsp != 0) { + _src = _src.deferred; + int _domainss = _src.dec_ndr_long(); + int _domainsi = _src.index; + _src.advance(12 * _domainss); + + if (domains == null) { + if (_domainss < 0 || _domainss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + domains = new LsarTrustInformation[_domainss]; + } + _src = _src.derive(_domainsi); + for (int _i = 0; _i < _domainss; _i++) { + if (domains[_i] == null) { + domains[_i] = new LsarTrustInformation(); + } + domains[_i].decode(_src); + } + } + } + } + public static class LsarTranslatedName extends NdrObject { + + public short sid_type; + public rpc.unicode_string name; + public int sid_index; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_short(sid_type); + _dst.enc_ndr_short(name.length); + _dst.enc_ndr_short(name.maximum_length); + _dst.enc_ndr_referent(name.buffer, 1); + _dst.enc_ndr_long(sid_index); + + if (name.buffer != null) { + _dst = _dst.deferred; + int _name_bufferl = name.length / 2; + int _name_buffers = name.maximum_length / 2; + _dst.enc_ndr_long(_name_buffers); + _dst.enc_ndr_long(0); + _dst.enc_ndr_long(_name_bufferl); + int _name_bufferi = _dst.index; + _dst.advance(2 * _name_bufferl); + + _dst = _dst.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + _dst.enc_ndr_short(name.buffer[_i]); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + sid_type = (short)_src.dec_ndr_short(); + _src.align(4); + if (name == null) { + name = new rpc.unicode_string(); + } + name.length = (short)_src.dec_ndr_short(); + name.maximum_length = (short)_src.dec_ndr_short(); + int _name_bufferp = _src.dec_ndr_long(); + sid_index = (int)_src.dec_ndr_long(); + + if (_name_bufferp != 0) { + _src = _src.deferred; + int _name_buffers = _src.dec_ndr_long(); + _src.dec_ndr_long(); + int _name_bufferl = _src.dec_ndr_long(); + int _name_bufferi = _src.index; + _src.advance(2 * _name_bufferl); + + if (name.buffer == null) { + if (_name_buffers < 0 || _name_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + name.buffer = new short[_name_buffers]; + } + _src = _src.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + name.buffer[_i] = (short)_src.dec_ndr_short(); + } + } + } + } + public static class LsarTransNameArray extends NdrObject { + + public int count; + public LsarTranslatedName[] names; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(names, 1); + + if (names != null) { + _dst = _dst.deferred; + int _namess = count; + _dst.enc_ndr_long(_namess); + int _namesi = _dst.index; + _dst.advance(16 * _namess); + + _dst = _dst.derive(_namesi); + for (int _i = 0; _i < _namess; _i++) { + names[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _namesp = _src.dec_ndr_long(); + + if (_namesp != 0) { + _src = _src.deferred; + int _namess = _src.dec_ndr_long(); + int _namesi = _src.index; + _src.advance(16 * _namess); + + if (names == null) { + if (_namess < 0 || _namess > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + names = new LsarTranslatedName[_namess]; + } + _src = _src.derive(_namesi); + for (int _i = 0; _i < _namess; _i++) { + if (names[_i] == null) { + names[_i] = new LsarTranslatedName(); + } + names[_i].decode(_src); + } + } + } + } + public static class LsarClose extends DcerpcMessage { + + public int getOpnum() { return 0x00; } + + public int retval; + public rpc.policy_handle handle; + + public LsarClose(rpc.policy_handle handle) { + this.handle = handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + handle.encode(_dst); + } + public void decode_out(NdrBuffer _src) throws NdrException { + handle.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static class LsarQueryInformationPolicy extends DcerpcMessage { + + public int getOpnum() { return 0x07; } + + public int retval; + public rpc.policy_handle handle; + public short level; + public NdrObject info; + + public LsarQueryInformationPolicy(rpc.policy_handle handle, short level, NdrObject info) { + this.handle = handle; + this.level = level; + this.info = info; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + handle.encode(_dst); + _dst.enc_ndr_short(level); + } + public void decode_out(NdrBuffer _src) throws NdrException { + int _infop = _src.dec_ndr_long(); + if (_infop != 0) { + _src.dec_ndr_short(); /* union discriminant */ + info.decode(_src); + + } + retval = (int)_src.dec_ndr_long(); + } + } + public static class LsarLookupSids extends DcerpcMessage { + + public int getOpnum() { return 0x0f; } + + public int retval; + public rpc.policy_handle handle; + public LsarSidArray sids; + public LsarRefDomainList domains; + public LsarTransNameArray names; + public short level; + public int count; + + public LsarLookupSids(rpc.policy_handle handle, + LsarSidArray sids, + LsarRefDomainList domains, + LsarTransNameArray names, + short level, + int count) { + this.handle = handle; + this.sids = sids; + this.domains = domains; + this.names = names; + this.level = level; + this.count = count; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + handle.encode(_dst); + sids.encode(_dst); + names.encode(_dst); + _dst.enc_ndr_short(level); + _dst.enc_ndr_long(count); + } + public void decode_out(NdrBuffer _src) throws NdrException { + int _domainsp = _src.dec_ndr_long(); + if (_domainsp != 0) { + if (domains == null) { /* YOYOYO */ + domains = new LsarRefDomainList(); + } + domains.decode(_src); + + } + names.decode(_src); + count = (int)_src.dec_ndr_long(); + retval = (int)_src.dec_ndr_long(); + } + } + public static class LsarOpenPolicy2 extends DcerpcMessage { + + public int getOpnum() { return 0x2c; } + + public int retval; + public String system_name; + public LsarObjectAttributes object_attributes; + public int desired_access; + public rpc.policy_handle policy_handle; + + public LsarOpenPolicy2(String system_name, + LsarObjectAttributes object_attributes, + int desired_access, + rpc.policy_handle policy_handle) { + this.system_name = system_name; + this.object_attributes = object_attributes; + this.desired_access = desired_access; + this.policy_handle = policy_handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + _dst.enc_ndr_referent(system_name, 1); + if (system_name != null) { + _dst.enc_ndr_string(system_name); + + } + object_attributes.encode(_dst); + _dst.enc_ndr_long(desired_access); + } + public void decode_out(NdrBuffer _src) throws NdrException { + policy_handle.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static class LsarQueryInformationPolicy2 extends DcerpcMessage { + + public int getOpnum() { return 0x2e; } + + public int retval; + public rpc.policy_handle handle; + public short level; + public NdrObject info; + + public LsarQueryInformationPolicy2(rpc.policy_handle handle, short level, NdrObject info) { + this.handle = handle; + this.level = level; + this.info = info; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + handle.encode(_dst); + _dst.enc_ndr_short(level); + } + public void decode_out(NdrBuffer _src) throws NdrException { + int _infop = _src.dec_ndr_long(); + if (_infop != 0) { + _src.dec_ndr_short(); /* union discriminant */ + info.decode(_src); + + } + retval = (int)_src.dec_ndr_long(); + } + } +} diff --git a/src/jcifs/dcerpc/msrpc/netdfs.idl b/src/jcifs/dcerpc/msrpc/netdfs.idl new file mode 100644 index 0000000..ff2760d --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/netdfs.idl @@ -0,0 +1,81 @@ +[ + uuid(4fc742e0-4a10-11cf-8273-00aa004ae673), + version(3.0) +] +interface netdfs +{ + import "../rpc.idl"; + + const uint32_t DFS_VOLUME_FLAVOR_STANDALONE = 0x100; + const uint32_t DFS_VOLUME_FLAVOR_AD_BLOB = 0x200; + + const uint32_t DFS_STORAGE_STATE_OFFLINE = 0x0001; + const uint32_t DFS_STORAGE_STATE_ONLINE = 0x0002; + const uint32_t DFS_STORAGE_STATE_ACTIVE = 0x0004; + + typedef struct { + [string] wchar_t *entry_path; + } DfsInfo1; + + typedef struct { + uint32_t count; + [size_is(count)] DfsInfo1 *s; + } DfsEnumArray1; + + typedef struct { + uint32_t state; + [string] wchar_t *server_name; + [string] wchar_t *share_name; + } DfsStorageInfo; + + typedef struct { + [string] wchar_t *path; + [string] wchar_t *comment; + uint32_t state; + uint32_t num_stores; + [size_is(num_stores)] DfsStorageInfo *stores; + } DfsInfo3; + + typedef struct { + uint32_t count; + [size_is(count)] DfsInfo3 *s; + } DfsEnumArray3; + + typedef struct { + [string] wchar_t *dfs_name; + } DfsInfo200; + + typedef struct { + uint32_t count; + [size_is(count)] DfsInfo200 *s; + } DfsEnumArray200; + + typedef struct { + uint32_t flags; + [string] wchar_t *dfs_name; + } DfsInfo300; + + typedef struct { + uint32_t count; + [size_is(count)] DfsInfo300 *s; + } DfsEnumArray300; + + typedef union { + [case(1)] DfsEnumArray1 *info1; + [case(3)] DfsEnumArray3 *info3; + [case(200)] DfsEnumArray200 *info200; + [case(300)] DfsEnumArray300 *info300; + } DfsEnumInfo; + + typedef struct { + uint32_t level, + [switch_is(level)] DfsEnumInfo e; + } DfsEnumStruct; + + [op(0x15)] + int NetrDfsEnumEx([in,string,unique] wchar_t dfs_name, + [in] uint32_t level, + [in] uint32_t prefmaxlen, + [in,out,unique] DfsEnumStruct *info, + [in,out,unique] uint32_t *totalentries); +} diff --git a/src/jcifs/dcerpc/msrpc/netdfs.java b/src/jcifs/dcerpc/msrpc/netdfs.java new file mode 100644 index 0000000..1baa582 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/netdfs.java @@ -0,0 +1,494 @@ +package jcifs.dcerpc.msrpc; + +import jcifs.dcerpc.*; +import jcifs.dcerpc.ndr.*; + +public class netdfs { + + public static String getSyntax() { + return "4fc742e0-4a10-11cf-8273-00aa004ae673:3.0"; + } + + public static final int DFS_VOLUME_FLAVOR_STANDALONE = 0x100; + public static final int DFS_VOLUME_FLAVOR_AD_BLOB = 0x200; + public static final int DFS_STORAGE_STATE_OFFLINE = 0x0001; + public static final int DFS_STORAGE_STATE_ONLINE = 0x0002; + public static final int DFS_STORAGE_STATE_ACTIVE = 0x0004; + public static class DfsInfo1 extends NdrObject { + + public String entry_path; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_referent(entry_path, 1); + + if (entry_path != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(entry_path); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + int _entry_pathp = _src.dec_ndr_long(); + + if (_entry_pathp != 0) { + _src = _src.deferred; + entry_path = _src.dec_ndr_string(); + + } + } + } + public static class DfsEnumArray1 extends NdrObject { + + public int count; + public DfsInfo1[] s; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(s, 1); + + if (s != null) { + _dst = _dst.deferred; + int _ss = count; + _dst.enc_ndr_long(_ss); + int _si = _dst.index; + _dst.advance(4 * _ss); + + _dst = _dst.derive(_si); + for (int _i = 0; _i < _ss; _i++) { + s[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _sp = _src.dec_ndr_long(); + + if (_sp != 0) { + _src = _src.deferred; + int _ss = _src.dec_ndr_long(); + int _si = _src.index; + _src.advance(4 * _ss); + + if (s == null) { + if (_ss < 0 || _ss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + s = new DfsInfo1[_ss]; + } + _src = _src.derive(_si); + for (int _i = 0; _i < _ss; _i++) { + if (s[_i] == null) { + s[_i] = new DfsInfo1(); + } + s[_i].decode(_src); + } + } + } + } + public static class DfsStorageInfo extends NdrObject { + + public int state; + public String server_name; + public String share_name; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(state); + _dst.enc_ndr_referent(server_name, 1); + _dst.enc_ndr_referent(share_name, 1); + + if (server_name != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(server_name); + + } + if (share_name != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(share_name); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + state = (int)_src.dec_ndr_long(); + int _server_namep = _src.dec_ndr_long(); + int _share_namep = _src.dec_ndr_long(); + + if (_server_namep != 0) { + _src = _src.deferred; + server_name = _src.dec_ndr_string(); + + } + if (_share_namep != 0) { + _src = _src.deferred; + share_name = _src.dec_ndr_string(); + + } + } + } + public static class DfsInfo3 extends NdrObject { + + public String path; + public String comment; + public int state; + public int num_stores; + public DfsStorageInfo[] stores; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_referent(path, 1); + _dst.enc_ndr_referent(comment, 1); + _dst.enc_ndr_long(state); + _dst.enc_ndr_long(num_stores); + _dst.enc_ndr_referent(stores, 1); + + if (path != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(path); + + } + if (comment != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(comment); + + } + if (stores != null) { + _dst = _dst.deferred; + int _storess = num_stores; + _dst.enc_ndr_long(_storess); + int _storesi = _dst.index; + _dst.advance(12 * _storess); + + _dst = _dst.derive(_storesi); + for (int _i = 0; _i < _storess; _i++) { + stores[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + int _pathp = _src.dec_ndr_long(); + int _commentp = _src.dec_ndr_long(); + state = (int)_src.dec_ndr_long(); + num_stores = (int)_src.dec_ndr_long(); + int _storesp = _src.dec_ndr_long(); + + if (_pathp != 0) { + _src = _src.deferred; + path = _src.dec_ndr_string(); + + } + if (_commentp != 0) { + _src = _src.deferred; + comment = _src.dec_ndr_string(); + + } + if (_storesp != 0) { + _src = _src.deferred; + int _storess = _src.dec_ndr_long(); + int _storesi = _src.index; + _src.advance(12 * _storess); + + if (stores == null) { + if (_storess < 0 || _storess > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + stores = new DfsStorageInfo[_storess]; + } + _src = _src.derive(_storesi); + for (int _i = 0; _i < _storess; _i++) { + if (stores[_i] == null) { + stores[_i] = new DfsStorageInfo(); + } + stores[_i].decode(_src); + } + } + } + } + public static class DfsEnumArray3 extends NdrObject { + + public int count; + public DfsInfo3[] s; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(s, 1); + + if (s != null) { + _dst = _dst.deferred; + int _ss = count; + _dst.enc_ndr_long(_ss); + int _si = _dst.index; + _dst.advance(20 * _ss); + + _dst = _dst.derive(_si); + for (int _i = 0; _i < _ss; _i++) { + s[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _sp = _src.dec_ndr_long(); + + if (_sp != 0) { + _src = _src.deferred; + int _ss = _src.dec_ndr_long(); + int _si = _src.index; + _src.advance(20 * _ss); + + if (s == null) { + if (_ss < 0 || _ss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + s = new DfsInfo3[_ss]; + } + _src = _src.derive(_si); + for (int _i = 0; _i < _ss; _i++) { + if (s[_i] == null) { + s[_i] = new DfsInfo3(); + } + s[_i].decode(_src); + } + } + } + } + public static class DfsInfo200 extends NdrObject { + + public String dfs_name; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_referent(dfs_name, 1); + + if (dfs_name != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(dfs_name); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + int _dfs_namep = _src.dec_ndr_long(); + + if (_dfs_namep != 0) { + _src = _src.deferred; + dfs_name = _src.dec_ndr_string(); + + } + } + } + public static class DfsEnumArray200 extends NdrObject { + + public int count; + public DfsInfo200[] s; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(s, 1); + + if (s != null) { + _dst = _dst.deferred; + int _ss = count; + _dst.enc_ndr_long(_ss); + int _si = _dst.index; + _dst.advance(4 * _ss); + + _dst = _dst.derive(_si); + for (int _i = 0; _i < _ss; _i++) { + s[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _sp = _src.dec_ndr_long(); + + if (_sp != 0) { + _src = _src.deferred; + int _ss = _src.dec_ndr_long(); + int _si = _src.index; + _src.advance(4 * _ss); + + if (s == null) { + if (_ss < 0 || _ss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + s = new DfsInfo200[_ss]; + } + _src = _src.derive(_si); + for (int _i = 0; _i < _ss; _i++) { + if (s[_i] == null) { + s[_i] = new DfsInfo200(); + } + s[_i].decode(_src); + } + } + } + } + public static class DfsInfo300 extends NdrObject { + + public int flags; + public String dfs_name; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(flags); + _dst.enc_ndr_referent(dfs_name, 1); + + if (dfs_name != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(dfs_name); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + flags = (int)_src.dec_ndr_long(); + int _dfs_namep = _src.dec_ndr_long(); + + if (_dfs_namep != 0) { + _src = _src.deferred; + dfs_name = _src.dec_ndr_string(); + + } + } + } + public static class DfsEnumArray300 extends NdrObject { + + public int count; + public DfsInfo300[] s; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(s, 1); + + if (s != null) { + _dst = _dst.deferred; + int _ss = count; + _dst.enc_ndr_long(_ss); + int _si = _dst.index; + _dst.advance(8 * _ss); + + _dst = _dst.derive(_si); + for (int _i = 0; _i < _ss; _i++) { + s[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _sp = _src.dec_ndr_long(); + + if (_sp != 0) { + _src = _src.deferred; + int _ss = _src.dec_ndr_long(); + int _si = _src.index; + _src.advance(8 * _ss); + + if (s == null) { + if (_ss < 0 || _ss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + s = new DfsInfo300[_ss]; + } + _src = _src.derive(_si); + for (int _i = 0; _i < _ss; _i++) { + if (s[_i] == null) { + s[_i] = new DfsInfo300(); + } + s[_i].decode(_src); + } + } + } + } + public static class DfsEnumStruct extends NdrObject { + + public int level; + public NdrObject e; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(level); + int _descr = level; + _dst.enc_ndr_long(_descr); + _dst.enc_ndr_referent(e, 1); + + if (e != null) { + _dst = _dst.deferred; + e.encode(_dst); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + level = (int)_src.dec_ndr_long(); + _src.dec_ndr_long(); /* union discriminant */ + int _ep = _src.dec_ndr_long(); + + if (_ep != 0) { + if (e == null) { /* YOYOYO */ + e = new DfsEnumArray1(); + } + _src = _src.deferred; + e.decode(_src); + + } + } + } + public static class NetrDfsEnumEx extends DcerpcMessage { + + public int getOpnum() { return 0x15; } + + public int retval; + public String dfs_name; + public int level; + public int prefmaxlen; + public DfsEnumStruct info; + public NdrLong totalentries; + + public NetrDfsEnumEx(String dfs_name, + int level, + int prefmaxlen, + DfsEnumStruct info, + NdrLong totalentries) { + this.dfs_name = dfs_name; + this.level = level; + this.prefmaxlen = prefmaxlen; + this.info = info; + this.totalentries = totalentries; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + _dst.enc_ndr_string(dfs_name); + _dst.enc_ndr_long(level); + _dst.enc_ndr_long(prefmaxlen); + _dst.enc_ndr_referent(info, 1); + if (info != null) { + info.encode(_dst); + + } + _dst.enc_ndr_referent(totalentries, 1); + if (totalentries != null) { + totalentries.encode(_dst); + + } + } + public void decode_out(NdrBuffer _src) throws NdrException { + int _infop = _src.dec_ndr_long(); + if (_infop != 0) { + if (info == null) { /* YOYOYO */ + info = new DfsEnumStruct(); + } + info.decode(_src); + + } + int _totalentriesp = _src.dec_ndr_long(); + if (_totalentriesp != 0) { + totalentries.decode(_src); + + } + retval = (int)_src.dec_ndr_long(); + } + } +} diff --git a/src/jcifs/dcerpc/msrpc/samr.idl b/src/jcifs/dcerpc/msrpc/samr.idl new file mode 100644 index 0000000..7ebb91e --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/samr.idl @@ -0,0 +1,96 @@ +[ + uuid(12345778-1234-abcd-ef00-0123456789ac), + version(1.0) +] +interface samr +{ + import "../rpc.idl"; + import "lsarpc.idl"; + + typedef [v1_enum] enum { + ACB_DISABLED = 0x00000001, /* 1 = User account disabled */ + ACB_HOMDIRREQ = 0x00000002, /* 1 = Home directory required */ + ACB_PWNOTREQ = 0x00000004, /* 1 = User password not required */ + ACB_TEMPDUP = 0x00000008, /* 1 = Temporary duplicate account */ + ACB_NORMAL = 0x00000010, /* 1 = Normal user account */ + ACB_MNS = 0x00000020, /* 1 = MNS logon user account */ + ACB_DOMTRUST = 0x00000040, /* 1 = Interdomain trust account */ + ACB_WSTRUST = 0x00000080, /* 1 = Workstation trust account */ + ACB_SVRTRUST = 0x00000100, /* 1 = Server trust account */ + ACB_PWNOEXP = 0x00000200, /* 1 = User password does not expire */ + ACB_AUTOLOCK = 0x00000400, /* 1 = Account auto locked */ + ACB_ENC_TXT_PWD_ALLOWED = 0x00000800, /* 1 = Encryped text password is allowed */ + ACB_SMARTCARD_REQUIRED = 0x00001000, /* 1 = Smart Card required */ + ACB_TRUSTED_FOR_DELEGATION = 0x00002000, /* 1 = Trusted for Delegation */ + ACB_NOT_DELEGATED = 0x00004000, /* 1 = Not delegated */ + ACB_USE_DES_KEY_ONLY = 0x00008000, /* 1 = Use DES key only */ + ACB_DONT_REQUIRE_PREAUTH = 0x00010000 /* 1 = Preauth not required */ + } SamrAcctFlags; + + [op(0x01)] + int SamrCloseHandle([in] policy_handle *handle); + + [op(0x39)] + int SamrConnect2([in,string,unique] wchar_t *system_name, + [in] uint32_t access_mask, + [out] policy_handle *handle); + + [op(0x3e)] + int SamrConnect4([in,string,unique] wchar_t *system_name, + [in] uint32_t unknown, + [in] uint32_t access_mask, + [out] policy_handle *handle); + + [op(0x07)] + int SamrOpenDomain([in] policy_handle *handle, + [in] uint32_t access_mask, + [in] sid_t *sid, + [out] policy_handle *domain_handle); + + typedef struct { + uint32_t idx; + unicode_string name; + } SamrSamEntry; + + typedef struct { + uint32_t count; + [size_is(count)] SamrSamEntry *entries; + } SamrSamArray; + + [op(0x0f)] + int SamrEnumerateAliasesInDomain([in] policy_handle *domain_handle, + [in,out] uint32_t *resume_handle, + [in] uint32_t acct_flags, + [out,unique] SamrSamArray *sam, + [out] uint32_t num_entries); + + [op(0x1b)] + int SamrOpenAlias([in] policy_handle *domain_handle, + [in] uint32_t access_mask, + [in] uint32_t rid, + [out] policy_handle *alias_handle); + + [op(0x21)] + int SamrGetMembersInAlias([in] policy_handle *alias_handle, + [out] LsarSidArray *sids); + + typedef [v1_enum] enum { + SE_GROUP_MANDATORY = 0x00000001, + SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002, + SE_GROUP_ENABLED = 0x00000004, + SE_GROUP_OWNER = 0x00000008, + SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010, + SE_GROUP_RESOURCE = 0x20000000, + SE_GROUP_LOGON_ID = 0xC0000000 + } SamrGroupAttrs; + + typedef struct { + uint32_t rid; + SamrGroupAttrs attributes; + } SamrRidWithAttribute; + + typedef struct { + uint32_t count; + [size_is(count)] SamrRidWithAttribute *rids; + } SamrRidWithAttributeArray; +} diff --git a/src/jcifs/dcerpc/msrpc/samr.java b/src/jcifs/dcerpc/msrpc/samr.java new file mode 100644 index 0000000..a64cb13 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/samr.java @@ -0,0 +1,413 @@ +package jcifs.dcerpc.msrpc; + +import jcifs.dcerpc.*; +import jcifs.dcerpc.ndr.*; + +public class samr { + + public static String getSyntax() { + return "12345778-1234-abcd-ef00-0123456789ac:1.0"; + } + + public static final int ACB_DISABLED = 1; + public static final int ACB_HOMDIRREQ = 2; + public static final int ACB_PWNOTREQ = 4; + public static final int ACB_TEMPDUP = 8; + public static final int ACB_NORMAL = 16; + public static final int ACB_MNS = 32; + public static final int ACB_DOMTRUST = 64; + public static final int ACB_WSTRUST = 128; + public static final int ACB_SVRTRUST = 256; + public static final int ACB_PWNOEXP = 512; + public static final int ACB_AUTOLOCK = 1024; + public static final int ACB_ENC_TXT_PWD_ALLOWED = 2048; + public static final int ACB_SMARTCARD_REQUIRED = 4096; + public static final int ACB_TRUSTED_FOR_DELEGATION = 8192; + public static final int ACB_NOT_DELEGATED = 16384; + public static final int ACB_USE_DES_KEY_ONLY = 32768; + public static final int ACB_DONT_REQUIRE_PREAUTH = 65536; + + public static class SamrCloseHandle extends DcerpcMessage { + + public int getOpnum() { return 0x01; } + + public int retval; + public rpc.policy_handle handle; + + public SamrCloseHandle(rpc.policy_handle handle) { + this.handle = handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + handle.encode(_dst); + } + public void decode_out(NdrBuffer _src) throws NdrException { + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrConnect2 extends DcerpcMessage { + + public int getOpnum() { return 0x39; } + + public int retval; + public String system_name; + public int access_mask; + public rpc.policy_handle handle; + + public SamrConnect2(String system_name, int access_mask, rpc.policy_handle handle) { + this.system_name = system_name; + this.access_mask = access_mask; + this.handle = handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + _dst.enc_ndr_referent(system_name, 1); + if (system_name != null) { + _dst.enc_ndr_string(system_name); + + } + _dst.enc_ndr_long(access_mask); + } + public void decode_out(NdrBuffer _src) throws NdrException { + handle.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrConnect4 extends DcerpcMessage { + + public int getOpnum() { return 0x3e; } + + public int retval; + public String system_name; + public int unknown; + public int access_mask; + public rpc.policy_handle handle; + + public SamrConnect4(String system_name, + int unknown, + int access_mask, + rpc.policy_handle handle) { + this.system_name = system_name; + this.unknown = unknown; + this.access_mask = access_mask; + this.handle = handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + _dst.enc_ndr_referent(system_name, 1); + if (system_name != null) { + _dst.enc_ndr_string(system_name); + + } + _dst.enc_ndr_long(unknown); + _dst.enc_ndr_long(access_mask); + } + public void decode_out(NdrBuffer _src) throws NdrException { + handle.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrOpenDomain extends DcerpcMessage { + + public int getOpnum() { return 0x07; } + + public int retval; + public rpc.policy_handle handle; + public int access_mask; + public rpc.sid_t sid; + public rpc.policy_handle domain_handle; + + public SamrOpenDomain(rpc.policy_handle handle, + int access_mask, + rpc.sid_t sid, + rpc.policy_handle domain_handle) { + this.handle = handle; + this.access_mask = access_mask; + this.sid = sid; + this.domain_handle = domain_handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + handle.encode(_dst); + _dst.enc_ndr_long(access_mask); + sid.encode(_dst); + } + public void decode_out(NdrBuffer _src) throws NdrException { + domain_handle.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrSamEntry extends NdrObject { + + public int idx; + public rpc.unicode_string name; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(idx); + _dst.enc_ndr_short(name.length); + _dst.enc_ndr_short(name.maximum_length); + _dst.enc_ndr_referent(name.buffer, 1); + + if (name.buffer != null) { + _dst = _dst.deferred; + int _name_bufferl = name.length / 2; + int _name_buffers = name.maximum_length / 2; + _dst.enc_ndr_long(_name_buffers); + _dst.enc_ndr_long(0); + _dst.enc_ndr_long(_name_bufferl); + int _name_bufferi = _dst.index; + _dst.advance(2 * _name_bufferl); + + _dst = _dst.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + _dst.enc_ndr_short(name.buffer[_i]); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + idx = (int)_src.dec_ndr_long(); + _src.align(4); + if (name == null) { + name = new rpc.unicode_string(); + } + name.length = (short)_src.dec_ndr_short(); + name.maximum_length = (short)_src.dec_ndr_short(); + int _name_bufferp = _src.dec_ndr_long(); + + if (_name_bufferp != 0) { + _src = _src.deferred; + int _name_buffers = _src.dec_ndr_long(); + _src.dec_ndr_long(); + int _name_bufferl = _src.dec_ndr_long(); + int _name_bufferi = _src.index; + _src.advance(2 * _name_bufferl); + + if (name.buffer == null) { + if (_name_buffers < 0 || _name_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + name.buffer = new short[_name_buffers]; + } + _src = _src.derive(_name_bufferi); + for (int _i = 0; _i < _name_bufferl; _i++) { + name.buffer[_i] = (short)_src.dec_ndr_short(); + } + } + } + } + public static class SamrSamArray extends NdrObject { + + public int count; + public SamrSamEntry[] entries; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(entries, 1); + + if (entries != null) { + _dst = _dst.deferred; + int _entriess = count; + _dst.enc_ndr_long(_entriess); + int _entriesi = _dst.index; + _dst.advance(12 * _entriess); + + _dst = _dst.derive(_entriesi); + for (int _i = 0; _i < _entriess; _i++) { + entries[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _entriesp = _src.dec_ndr_long(); + + if (_entriesp != 0) { + _src = _src.deferred; + int _entriess = _src.dec_ndr_long(); + int _entriesi = _src.index; + _src.advance(12 * _entriess); + + if (entries == null) { + if (_entriess < 0 || _entriess > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + entries = new SamrSamEntry[_entriess]; + } + _src = _src.derive(_entriesi); + for (int _i = 0; _i < _entriess; _i++) { + if (entries[_i] == null) { + entries[_i] = new SamrSamEntry(); + } + entries[_i].decode(_src); + } + } + } + } + public static class SamrEnumerateAliasesInDomain extends DcerpcMessage { + + public int getOpnum() { return 0x0f; } + + public int retval; + public rpc.policy_handle domain_handle; + public int resume_handle; + public int acct_flags; + public SamrSamArray sam; + public int num_entries; + + public SamrEnumerateAliasesInDomain(rpc.policy_handle domain_handle, + int resume_handle, + int acct_flags, + SamrSamArray sam, + int num_entries) { + this.domain_handle = domain_handle; + this.resume_handle = resume_handle; + this.acct_flags = acct_flags; + this.sam = sam; + this.num_entries = num_entries; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + domain_handle.encode(_dst); + _dst.enc_ndr_long(resume_handle); + _dst.enc_ndr_long(acct_flags); + } + public void decode_out(NdrBuffer _src) throws NdrException { + resume_handle = (int)_src.dec_ndr_long(); + int _samp = _src.dec_ndr_long(); + if (_samp != 0) { + if (sam == null) { /* YOYOYO */ + sam = new SamrSamArray(); + } + sam.decode(_src); + + } + num_entries = (int)_src.dec_ndr_long(); + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrOpenAlias extends DcerpcMessage { + + public int getOpnum() { return 0x1b; } + + public int retval; + public rpc.policy_handle domain_handle; + public int access_mask; + public int rid; + public rpc.policy_handle alias_handle; + + public SamrOpenAlias(rpc.policy_handle domain_handle, + int access_mask, + int rid, + rpc.policy_handle alias_handle) { + this.domain_handle = domain_handle; + this.access_mask = access_mask; + this.rid = rid; + this.alias_handle = alias_handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + domain_handle.encode(_dst); + _dst.enc_ndr_long(access_mask); + _dst.enc_ndr_long(rid); + } + public void decode_out(NdrBuffer _src) throws NdrException { + alias_handle.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrGetMembersInAlias extends DcerpcMessage { + + public int getOpnum() { return 0x21; } + + public int retval; + public rpc.policy_handle alias_handle; + public lsarpc.LsarSidArray sids; + + public SamrGetMembersInAlias(rpc.policy_handle alias_handle, lsarpc.LsarSidArray sids) { + this.alias_handle = alias_handle; + this.sids = sids; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + alias_handle.encode(_dst); + } + public void decode_out(NdrBuffer _src) throws NdrException { + sids.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static final int SE_GROUP_MANDATORY = 1; + public static final int SE_GROUP_ENABLED_BY_DEFAULT = 2; + public static final int SE_GROUP_ENABLED = 4; + public static final int SE_GROUP_OWNER = 8; + public static final int SE_GROUP_USE_FOR_DENY_ONLY = 16; + public static final int SE_GROUP_RESOURCE = 536870912; + public static final int SE_GROUP_LOGON_ID = -1073741824; + + public static class SamrRidWithAttribute extends NdrObject { + + public int rid; + public int attributes; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(rid); + _dst.enc_ndr_long(attributes); + + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + rid = (int)_src.dec_ndr_long(); + attributes = (int)_src.dec_ndr_long(); + + } + } + public static class SamrRidWithAttributeArray extends NdrObject { + + public int count; + public SamrRidWithAttribute[] rids; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(rids, 1); + + if (rids != null) { + _dst = _dst.deferred; + int _ridss = count; + _dst.enc_ndr_long(_ridss); + int _ridsi = _dst.index; + _dst.advance(8 * _ridss); + + _dst = _dst.derive(_ridsi); + for (int _i = 0; _i < _ridss; _i++) { + rids[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _ridsp = _src.dec_ndr_long(); + + if (_ridsp != 0) { + _src = _src.deferred; + int _ridss = _src.dec_ndr_long(); + int _ridsi = _src.index; + _src.advance(8 * _ridss); + + if (rids == null) { + if (_ridss < 0 || _ridss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + rids = new SamrRidWithAttribute[_ridss]; + } + _src = _src.derive(_ridsi); + for (int _i = 0; _i < _ridss; _i++) { + if (rids[_i] == null) { + rids[_i] = new SamrRidWithAttribute(); + } + rids[_i].decode(_src); + } + } + } + } +} diff --git a/src/jcifs/dcerpc/msrpc/srvsvc.idl b/src/jcifs/dcerpc/msrpc/srvsvc.idl new file mode 100644 index 0000000..3e692fb --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/srvsvc.idl @@ -0,0 +1,107 @@ +[ + uuid(4b324fc8-1670-01d3-1278-5a47bf6ee188), + version(3.0) +] +interface srvsvc +{ + import "../rpc.idl"; + + typedef struct { + [string] wchar_t *netname; + } ShareInfo0; + + typedef struct { + int count; + [size_is(count)] ShareInfo0 *array; + } ShareInfoCtr0; + + typedef struct { + [string] wchar_t *netname; + int type; + [string] wchar_t *remark; + } ShareInfo1; + + typedef struct { + int count; + [size_is(count)] ShareInfo1 *array; + } ShareInfoCtr1; + + typedef struct { + [string] wchar_t *netname; + int type; + [string] wchar_t *remark; + uint32_t permissions; + uint32_t max_uses; + uint32_t current_uses; + [string] wchar_t *path; + [string] wchar_t *password; + uint32_t sd_size; + [size_is(sd_size)] uint8_t *security_descriptor; + } ShareInfo502; + + typedef struct { + int count; + [size_is(count)] ShareInfo502 *array; + } ShareInfoCtr502; + + typedef [switch_type(int)] union { + [case(0)] ShareInfo0 *info0; + [case(1)] ShareInfo1 *info1; + [case(502)] ShareInfo502 *info1; + } ShareInfo; + + typedef [switch_type(int)] union { + [case(0)] ShareInfoCtr0 *info0; + [case(1)] ShareInfoCtr1 *info1; + [case(502)] ShareInfoCtr502 *info1; + } ShareCtr; + + [op(0x0f)] + int ShareEnumAll([in,string,unique] wchar_t *servername, + [in,out] int *level, + [in,out,switch_is(*level)] ShareCtr *info, + [in] unsigned long prefmaxlen, + [out] unsigned long *totalentries, + [in,out] unsigned long *resume_handle); + + [op(0x10)] + int ShareGetInfo([in,string,unique] wchar_t *servername, + [in,string] wchar_t *sharename, + [in] int level, + [out,switch_is(level)] ShareInfo *info); + + typedef struct { + unsigned long platform_id; + [string] wchar_t *name; + } ServerInfo100; + + typedef [switch_type(int)] union { + [case(0)] ServerInfo100 *info0; + } ServerInfo; + + [op(0x15)] + int ServerGetInfo([in,string,unique] wchar_t *servername, + [in] int level, + [out,switch_is(level)] ServerInfo *info); + + typedef struct { + uint32_t elapsedt; + uint32_t msecs; + uint32_t hours; + uint32_t mins; + uint32_t secs; + uint32_t hunds; + uint32_t timezone; + uint32_t tinterval; + uint32_t day; + uint32_t month; + uint32_t year; + uint32_t weekday; + } TimeOfDayInfo; + + [op(0x1c)] + int RemoteTOD([in,string,unique] wchar_t *servername, + [out,unique] TimeOfDayInfo *info); +} + + diff --git a/src/jcifs/dcerpc/msrpc/srvsvc.java b/src/jcifs/dcerpc/msrpc/srvsvc.java new file mode 100644 index 0000000..68eeaac --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/srvsvc.java @@ -0,0 +1,582 @@ +package jcifs.dcerpc.msrpc; + +import jcifs.dcerpc.*; +import jcifs.dcerpc.ndr.*; + +import jcifs.util.Hexdump; + +public class srvsvc { + + public static String getSyntax() { + return "4b324fc8-1670-01d3-1278-5a47bf6ee188:3.0"; + } + + public static class ShareInfo0 extends NdrObject { + + public String netname; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_referent(netname, 1); + + if (netname != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(netname); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + int _netnamep = _src.dec_ndr_long(); + + if (_netnamep != 0) { + _src = _src.deferred; + netname = _src.dec_ndr_string(); + + } + } + } + public static class ShareInfoCtr0 extends NdrObject { + + public int count; + public ShareInfo0[] array; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(array, 1); + + if (array != null) { + _dst = _dst.deferred; + int _arrays = count; + _dst.enc_ndr_long(_arrays); + int _arrayi = _dst.index; + _dst.advance(4 * _arrays); + + _dst = _dst.derive(_arrayi); + for (int _i = 0; _i < _arrays; _i++) { + array[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _arrayp = _src.dec_ndr_long(); + + if (_arrayp != 0) { + _src = _src.deferred; + int _arrays = _src.dec_ndr_long(); + int _arrayi = _src.index; + _src.advance(4 * _arrays); + + if (array == null) { + if (_arrays < 0 || _arrays > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + array = new ShareInfo0[_arrays]; + } + _src = _src.derive(_arrayi); + for (int _i = 0; _i < _arrays; _i++) { + if (array[_i] == null) { + array[_i] = new ShareInfo0(); + } + array[_i].decode(_src); + } + } + } + } + public static class ShareInfo1 extends NdrObject { + + public String netname; + public int type; + public String remark; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_referent(netname, 1); + _dst.enc_ndr_long(type); + _dst.enc_ndr_referent(remark, 1); + + if (netname != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(netname); + + } + if (remark != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(remark); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + int _netnamep = _src.dec_ndr_long(); + type = (int)_src.dec_ndr_long(); + int _remarkp = _src.dec_ndr_long(); + + if (_netnamep != 0) { + _src = _src.deferred; + netname = _src.dec_ndr_string(); + + } + if (_remarkp != 0) { + _src = _src.deferred; + remark = _src.dec_ndr_string(); + + } + } + } + public static class ShareInfoCtr1 extends NdrObject { + + public int count; + public ShareInfo1[] array; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(array, 1); + + if (array != null) { + _dst = _dst.deferred; + int _arrays = count; + _dst.enc_ndr_long(_arrays); + int _arrayi = _dst.index; + _dst.advance(12 * _arrays); + + _dst = _dst.derive(_arrayi); + for (int _i = 0; _i < _arrays; _i++) { + array[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _arrayp = _src.dec_ndr_long(); + + if (_arrayp != 0) { + _src = _src.deferred; + int _arrays = _src.dec_ndr_long(); + int _arrayi = _src.index; + _src.advance(12 * _arrays); + + if (array == null) { + if (_arrays < 0 || _arrays > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + array = new ShareInfo1[_arrays]; + } + _src = _src.derive(_arrayi); + for (int _i = 0; _i < _arrays; _i++) { + if (array[_i] == null) { + array[_i] = new ShareInfo1(); + } + array[_i].decode(_src); + } + } + } + } + public static class ShareInfo502 extends NdrObject { + + public String netname; + public int type; + public String remark; + public int permissions; + public int max_uses; + public int current_uses; + public String path; + public String password; + public int sd_size; + public byte[] security_descriptor; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_referent(netname, 1); + _dst.enc_ndr_long(type); + _dst.enc_ndr_referent(remark, 1); + _dst.enc_ndr_long(permissions); + _dst.enc_ndr_long(max_uses); + _dst.enc_ndr_long(current_uses); + _dst.enc_ndr_referent(path, 1); + _dst.enc_ndr_referent(password, 1); + _dst.enc_ndr_long(sd_size); + _dst.enc_ndr_referent(security_descriptor, 1); + + if (netname != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(netname); + + } + if (remark != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(remark); + + } + if (path != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(path); + + } + if (password != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(password); + + } + if (security_descriptor != null) { + _dst = _dst.deferred; + int _security_descriptors = sd_size; + _dst.enc_ndr_long(_security_descriptors); + int _security_descriptori = _dst.index; + _dst.advance(1 * _security_descriptors); + + _dst = _dst.derive(_security_descriptori); + for (int _i = 0; _i < _security_descriptors; _i++) { + _dst.enc_ndr_small(security_descriptor[_i]); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + int _netnamep = _src.dec_ndr_long(); + type = (int)_src.dec_ndr_long(); + int _remarkp = _src.dec_ndr_long(); + permissions = (int)_src.dec_ndr_long(); + max_uses = (int)_src.dec_ndr_long(); + current_uses = (int)_src.dec_ndr_long(); + int _pathp = _src.dec_ndr_long(); + int _passwordp = _src.dec_ndr_long(); + sd_size = (int)_src.dec_ndr_long(); + int _security_descriptorp = _src.dec_ndr_long(); + + if (_netnamep != 0) { + _src = _src.deferred; + netname = _src.dec_ndr_string(); + + } + if (_remarkp != 0) { + _src = _src.deferred; + remark = _src.dec_ndr_string(); + + } + if (_pathp != 0) { + _src = _src.deferred; + path = _src.dec_ndr_string(); + + } + if (_passwordp != 0) { + _src = _src.deferred; + password = _src.dec_ndr_string(); + + } + if (_security_descriptorp != 0) { + _src = _src.deferred; + int _security_descriptors = _src.dec_ndr_long(); + int _security_descriptori = _src.index; + _src.advance(1 * _security_descriptors); + + if (security_descriptor == null) { + if (_security_descriptors < 0 || _security_descriptors > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + security_descriptor = new byte[_security_descriptors]; + } + _src = _src.derive(_security_descriptori); + for (int _i = 0; _i < _security_descriptors; _i++) { + security_descriptor[_i] = (byte)_src.dec_ndr_small(); + } + } + } + } + public static class ShareInfoCtr502 extends NdrObject { + + public int count; + public ShareInfo502[] array; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(array, 1); + + if (array != null) { + _dst = _dst.deferred; + int _arrays = count; + _dst.enc_ndr_long(_arrays); + int _arrayi = _dst.index; + _dst.advance(40 * _arrays); + + _dst = _dst.derive(_arrayi); + for (int _i = 0; _i < _arrays; _i++) { + array[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _arrayp = _src.dec_ndr_long(); + + if (_arrayp != 0) { + _src = _src.deferred; + int _arrays = _src.dec_ndr_long(); + int _arrayi = _src.index; + _src.advance(40 * _arrays); + + if (array == null) { + if (_arrays < 0 || _arrays > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + array = new ShareInfo502[_arrays]; + } + _src = _src.derive(_arrayi); + for (int _i = 0; _i < _arrays; _i++) { + if (array[_i] == null) { + array[_i] = new ShareInfo502(); + } + array[_i].decode(_src); + } + } + } + } + public static class ShareEnumAll extends DcerpcMessage { + + public int getOpnum() { return 0x0f; } + + public int retval; + public String servername; + public int level; + public NdrObject info; + public int prefmaxlen; + public int totalentries; + public int resume_handle; + + public ShareEnumAll(String servername, + int level, + NdrObject info, + int prefmaxlen, + int totalentries, + int resume_handle) { + this.servername = servername; + this.level = level; + this.info = info; + this.prefmaxlen = prefmaxlen; + this.totalentries = totalentries; + this.resume_handle = resume_handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + _dst.enc_ndr_referent(servername, 1); + if (servername != null) { + _dst.enc_ndr_string(servername); + + } + _dst.enc_ndr_long(level); + int _descr = level; + _dst.enc_ndr_long(_descr); + _dst.enc_ndr_referent(info, 1); + if (info != null) { + _dst = _dst.deferred; + info.encode(_dst); + + } + _dst.enc_ndr_long(prefmaxlen); + _dst.enc_ndr_long(resume_handle); + } + public void decode_out(NdrBuffer _src) throws NdrException { + level = (int)_src.dec_ndr_long(); + _src.dec_ndr_long(); /* union discriminant */ + int _infop = _src.dec_ndr_long(); + if (_infop != 0) { + if (info == null) { /* YOYOYO */ + info = new ShareInfoCtr0(); + } + _src = _src.deferred; + info.decode(_src); + + } + totalentries = (int)_src.dec_ndr_long(); + resume_handle = (int)_src.dec_ndr_long(); + retval = (int)_src.dec_ndr_long(); + } + } + public static class ShareGetInfo extends DcerpcMessage { + + public int getOpnum() { return 0x10; } + + public int retval; + public String servername; + public String sharename; + public int level; + public NdrObject info; + + public ShareGetInfo(String servername, + String sharename, + int level, + NdrObject info) { + this.servername = servername; + this.sharename = sharename; + this.level = level; + this.info = info; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + _dst.enc_ndr_referent(servername, 1); + if (servername != null) { + _dst.enc_ndr_string(servername); + + } + _dst.enc_ndr_string(sharename); + _dst.enc_ndr_long(level); + } + public void decode_out(NdrBuffer _src) throws NdrException { + _src.dec_ndr_long(); /* union discriminant */ + int _infop = _src.dec_ndr_long(); + if (_infop != 0) { + if (info == null) { /* YOYOYO */ + info = new ShareInfo0(); + } + _src = _src.deferred; + info.decode(_src); + + } + retval = (int)_src.dec_ndr_long(); + } + } + public static class ServerInfo100 extends NdrObject { + + public int platform_id; + public String name; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(platform_id); + _dst.enc_ndr_referent(name, 1); + + if (name != null) { + _dst = _dst.deferred; + _dst.enc_ndr_string(name); + + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + platform_id = (int)_src.dec_ndr_long(); + int _namep = _src.dec_ndr_long(); + + if (_namep != 0) { + _src = _src.deferred; + name = _src.dec_ndr_string(); + + } + } + } + public static class ServerGetInfo extends DcerpcMessage { + + public int getOpnum() { return 0x15; } + + public int retval; + public String servername; + public int level; + public NdrObject info; + + public ServerGetInfo(String servername, int level, NdrObject info) { + this.servername = servername; + this.level = level; + this.info = info; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + _dst.enc_ndr_referent(servername, 1); + if (servername != null) { + _dst.enc_ndr_string(servername); + + } + _dst.enc_ndr_long(level); + } + public void decode_out(NdrBuffer _src) throws NdrException { + _src.dec_ndr_long(); /* union discriminant */ + int _infop = _src.dec_ndr_long(); + if (_infop != 0) { + if (info == null) { /* YOYOYO */ + info = new ServerInfo100(); + } + _src = _src.deferred; + info.decode(_src); + + } + retval = (int)_src.dec_ndr_long(); + } + } + public static class TimeOfDayInfo extends NdrObject { + + public int elapsedt; + public int msecs; + public int hours; + public int mins; + public int secs; + public int hunds; + public int timezone; + public int tinterval; + public int day; + public int month; + public int year; + public int weekday; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(elapsedt); + _dst.enc_ndr_long(msecs); + _dst.enc_ndr_long(hours); + _dst.enc_ndr_long(mins); + _dst.enc_ndr_long(secs); + _dst.enc_ndr_long(hunds); + _dst.enc_ndr_long(timezone); + _dst.enc_ndr_long(tinterval); + _dst.enc_ndr_long(day); + _dst.enc_ndr_long(month); + _dst.enc_ndr_long(year); + _dst.enc_ndr_long(weekday); + + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + elapsedt = (int)_src.dec_ndr_long(); + msecs = (int)_src.dec_ndr_long(); + hours = (int)_src.dec_ndr_long(); + mins = (int)_src.dec_ndr_long(); + secs = (int)_src.dec_ndr_long(); + hunds = (int)_src.dec_ndr_long(); + timezone = (int)_src.dec_ndr_long(); + tinterval = (int)_src.dec_ndr_long(); + day = (int)_src.dec_ndr_long(); + month = (int)_src.dec_ndr_long(); + year = (int)_src.dec_ndr_long(); + weekday = (int)_src.dec_ndr_long(); + + } + } + public static class RemoteTOD extends DcerpcMessage { + + public int getOpnum() { return 0x1c; } + + public int retval; + public String servername; + public TimeOfDayInfo info; + + public RemoteTOD(String servername, TimeOfDayInfo info) { + this.servername = servername; + this.info = info; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + _dst.enc_ndr_referent(servername, 1); + if (servername != null) { + _dst.enc_ndr_string(servername); + + } + } + public void decode_out(NdrBuffer _src) throws NdrException { + int _infop = _src.dec_ndr_long(); + if (_infop != 0) { + if (info == null) { /* YOYOYO */ + info = new TimeOfDayInfo(); + } + info.decode(_src); + + } + retval = (int)_src.dec_ndr_long(); + } + } +} diff --git a/src/jcifs/dcerpc/ndr/NdrBuffer.java b/src/jcifs/dcerpc/ndr/NdrBuffer.java new file mode 100644 index 0000000..ef71c1a --- /dev/null +++ b/src/jcifs/dcerpc/ndr/NdrBuffer.java @@ -0,0 +1,231 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.ndr; + +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import jcifs.util.Encdec; + +public class NdrBuffer { + int referent; + HashMap referents; + + static class Entry { + int referent; + Object obj; + } + + public byte[] buf; + public int start; + public int index; + public int length; + public NdrBuffer deferred; + + public NdrBuffer(byte[] buf, int start) { + this.buf = buf; + this.start = index = start; + length = 0; + deferred = this; + } + + public NdrBuffer derive(int idx) { + NdrBuffer nb = new NdrBuffer(buf, start); + nb.index = idx; + nb.deferred = deferred; + return nb; + } + + + + public void reset() { + this.index = start; + length = 0; + deferred = this; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + public int getCapacity() { + return buf.length - start; + } + public int getTailSpace() { + return buf.length - index; + } + public byte[] getBuffer() { + return buf; + } + public int align(int boundary, byte value) { + int n = align(boundary); + int i = n; + while (i > 0) { + buf[index - i] = value; + i--; + } + return n; + } + public void writeOctetArray(byte[] b, int i, int l) { + System.arraycopy(b, i, buf, index, l); + advance(l); + } + public void readOctetArray(byte[] b, int i, int l) { + System.arraycopy(buf, index, b, i, l); + advance(l); + } + + + public int getLength() { + return deferred.length; + } + public void setLength(int length) { + deferred.length = length; + } + public void advance(int n) { + index += n; + if ((index - start) > deferred.length) { + deferred.length = index - start; + } + } + public int align(int boundary) { + int m = boundary - 1; + int i = index - start; + int n = ((i + m) & ~m) - i; + advance(n); + return n; + } + public void enc_ndr_small(int s) { + buf[index] = (byte)(s & 0xFF); + advance(1); + } + public int dec_ndr_small() { + int val = buf[index] & 0xFF; + advance(1); + return val; + } + public void enc_ndr_short(int s) { + align(2); + Encdec.enc_uint16le((short)s, buf, index); + advance(2); + } + public int dec_ndr_short() { + align(2); + int val = Encdec.dec_uint16le(buf, index); + advance(2); + return val; + } + public void enc_ndr_long(int l) { + align(4); + Encdec.enc_uint32le(l, buf, index); + advance(4); + } + public int dec_ndr_long() { + align(4); + int val = Encdec.dec_uint32le(buf, index); + advance(4); + return val; + } + public void enc_ndr_hyper(long h) { + align(8); + Encdec.enc_uint64le(h, buf, index); + advance(8); + } + public long dec_ndr_hyper() { + align(8); + long val = Encdec.dec_uint64le(buf, index); + advance(8); + return val; + } + /* float */ + /* double */ + public void enc_ndr_string(String s) { + align(4); + int i = index; + int len = s.length(); + Encdec.enc_uint32le(len + 1, buf, i); i += 4; + Encdec.enc_uint32le(0, buf, i); i += 4; + Encdec.enc_uint32le(len + 1, buf, i); i += 4; + try { + System.arraycopy(s.getBytes("UTF-16LE"), 0, buf, i, len * 2); + } catch( UnsupportedEncodingException uee ) { + } + i += len * 2; + buf[i++] = (byte)'\0'; + buf[i++] = (byte)'\0'; + advance(i - index); + } + public String dec_ndr_string() throws NdrException { + align(4); + int i = index; + String val = null; + int len = Encdec.dec_uint32le(buf, i); + i += 12; + if (len != 0) { + len--; + int size = len * 2; + try { + if (size < 0 || size > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + val = new String(buf, i, size, "UTF-16LE"); + i += size + 2; + } catch( UnsupportedEncodingException uee ) { + } + } + advance(i - index); + return val; + } + private int getDceReferent(Object obj) { + Entry e; + + if (referents == null) { + referents = new HashMap(); + referent = 1; + } + + if ((e = (Entry)referents.get(obj)) == null) { + e = new Entry(); + e.referent = referent++; + e.obj = obj; + referents.put(obj, e); + } + + return e.referent; + } + public void enc_ndr_referent(Object obj, int type) { + if (obj == null) { + enc_ndr_long(0); + return; + } + switch (type) { + case 1: /* unique */ + case 3: /* ref */ + enc_ndr_long(System.identityHashCode(obj)); + return; + case 2: /* ptr */ + enc_ndr_long(getDceReferent(obj)); + return; + } + } + + public String toString() { + return "start=" + start + ",index=" + index + ",length=" + getLength(); + } +} + diff --git a/src/jcifs/dcerpc/ndr/NdrException.java b/src/jcifs/dcerpc/ndr/NdrException.java new file mode 100644 index 0000000..29173f4 --- /dev/null +++ b/src/jcifs/dcerpc/ndr/NdrException.java @@ -0,0 +1,32 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.ndr; + +import java.io.IOException; + +public class NdrException extends IOException { + + public static final String NO_NULL_REF = "ref pointer cannot be null"; + public static final String INVALID_CONFORMANCE = "invalid array conformance"; + + public NdrException( String msg ) { + super( msg ); + } +} diff --git a/src/jcifs/dcerpc/ndr/NdrHyper.java b/src/jcifs/dcerpc/ndr/NdrHyper.java new file mode 100644 index 0000000..42d0bd0 --- /dev/null +++ b/src/jcifs/dcerpc/ndr/NdrHyper.java @@ -0,0 +1,37 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.ndr; + +public class NdrHyper extends NdrObject { + + public long value; + + public NdrHyper(long value) { + this.value = value; + } + + public void encode(NdrBuffer dst) throws NdrException { + dst.enc_ndr_hyper(value); + } + public void decode(NdrBuffer src) throws NdrException { + value = src.dec_ndr_hyper(); + } +} + diff --git a/src/jcifs/dcerpc/ndr/NdrLong.java b/src/jcifs/dcerpc/ndr/NdrLong.java new file mode 100644 index 0000000..dafaf4c --- /dev/null +++ b/src/jcifs/dcerpc/ndr/NdrLong.java @@ -0,0 +1,37 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.ndr; + +public class NdrLong extends NdrObject { + + public int value; + + public NdrLong(int value) { + this.value = value; + } + + public void encode(NdrBuffer dst) throws NdrException { + dst.enc_ndr_long(value); + } + public void decode(NdrBuffer src) throws NdrException { + value = src.dec_ndr_long(); + } +} + diff --git a/src/jcifs/dcerpc/ndr/NdrObject.java b/src/jcifs/dcerpc/ndr/NdrObject.java new file mode 100644 index 0000000..969dbf3 --- /dev/null +++ b/src/jcifs/dcerpc/ndr/NdrObject.java @@ -0,0 +1,27 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.ndr; + +public abstract class NdrObject { + + public abstract void encode(NdrBuffer dst) throws NdrException; + public abstract void decode(NdrBuffer src) throws NdrException; +} + diff --git a/src/jcifs/dcerpc/ndr/NdrShort.java b/src/jcifs/dcerpc/ndr/NdrShort.java new file mode 100644 index 0000000..992e0b2 --- /dev/null +++ b/src/jcifs/dcerpc/ndr/NdrShort.java @@ -0,0 +1,37 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.ndr; + +public class NdrShort extends NdrObject { + + public int value; + + public NdrShort(int value) { + this.value = value & 0xFF; + } + + public void encode(NdrBuffer dst) throws NdrException { + dst.enc_ndr_short(value); + } + public void decode(NdrBuffer src) throws NdrException { + value = src.dec_ndr_short(); + } +} + diff --git a/src/jcifs/dcerpc/ndr/NdrSmall.java b/src/jcifs/dcerpc/ndr/NdrSmall.java new file mode 100644 index 0000000..f88e653 --- /dev/null +++ b/src/jcifs/dcerpc/ndr/NdrSmall.java @@ -0,0 +1,37 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.dcerpc.ndr; + +public class NdrSmall extends NdrObject { + + public int value; + + public NdrSmall(int value) { + this.value = value & 0xFF; + } + + public void encode(NdrBuffer dst) throws NdrException { + dst.enc_ndr_small(value); + } + public void decode(NdrBuffer src) throws NdrException { + value = src.dec_ndr_small(); + } +} + diff --git a/src/jcifs/dcerpc/rpc.idl b/src/jcifs/dcerpc/rpc.idl new file mode 100644 index 0000000..02aff63 --- /dev/null +++ b/src/jcifs/dcerpc/rpc.idl @@ -0,0 +1,63 @@ +interface rpc +{ + /* base types */ + + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + + /* dce */ + + typedef struct { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[6]; + } uuid_t; + + /* win32 stuff */ + + typedef struct { + uint32_t type; + uuid_t uuid; + } policy_handle; + + /* + * typedef struct _UNICODE_STRING + * USHORT Length; + * USHORT MaximumLength; + * [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer; + * } UNICODE_STRING; + */ + + typedef struct { + uint16_t length; + uint16_t maximum_length; + [length_is(length / 2),size_is(maximum_length / 2)] uint16_t *buffer; + } unicode_string; + + /* + * typedef struct _SID_IDENTIFIER_AUTHORITY { + * UCHAR Value[6]; + * } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY; + * + * #define SECURITY_NT_AUTHORITY {0,0,0,0,0,5} + * + * typedef struct _SID { + * UCHAR Revision; + * UCHAR SubAuthorityCount; + * SID_IDENTIFIER_AUTHORITY IdentifierAuthority; + * [size_is(SubAuthorityCount)] ULONG SubAuthority[*]; + * } SID, *PSID; + */ + + typedef struct { + uint8_t revision; + uint8_t sub_authority_count; + uint8_t identifier_authority[6]; + [size_is(sub_authority_count)] uint32_t sub_authority[*]; + } sid_t; +} + diff --git a/src/jcifs/dcerpc/rpc.java b/src/jcifs/dcerpc/rpc.java new file mode 100644 index 0000000..897efc5 --- /dev/null +++ b/src/jcifs/dcerpc/rpc.java @@ -0,0 +1,212 @@ +package jcifs.dcerpc; + +import jcifs.dcerpc.ndr.*; +import jcifs.util.*; + +public class rpc { + + public static class uuid_t extends NdrObject { + + public int time_low; + public short time_mid; + public short time_hi_and_version; + public byte clock_seq_hi_and_reserved; + public byte clock_seq_low; + public byte[] node; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(time_low); + _dst.enc_ndr_short(time_mid); + _dst.enc_ndr_short(time_hi_and_version); + _dst.enc_ndr_small(clock_seq_hi_and_reserved); + _dst.enc_ndr_small(clock_seq_low); + int _nodes = 6; + int _nodei = _dst.index; + _dst.advance(1 * _nodes); + + _dst = _dst.derive(_nodei); + for (int _i = 0; _i < _nodes; _i++) { + _dst.enc_ndr_small(node[_i]); + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + time_low = (int)_src.dec_ndr_long(); + time_mid = (short)_src.dec_ndr_short(); + time_hi_and_version = (short)_src.dec_ndr_short(); + clock_seq_hi_and_reserved = (byte)_src.dec_ndr_small(); + clock_seq_low = (byte)_src.dec_ndr_small(); + int _nodes = 6; + int _nodei = _src.index; + _src.advance(1 * _nodes); + + if (node == null) { + if (_nodes < 0 || _nodes > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + node = new byte[_nodes]; + } + _src = _src.derive(_nodei); + for (int _i = 0; _i < _nodes; _i++) { + node[_i] = (byte)_src.dec_ndr_small(); + } + } + } + public static class policy_handle extends NdrObject { + + public int type; + public uuid_t uuid; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(type); + _dst.enc_ndr_long(uuid.time_low); + _dst.enc_ndr_short(uuid.time_mid); + _dst.enc_ndr_short(uuid.time_hi_and_version); + _dst.enc_ndr_small(uuid.clock_seq_hi_and_reserved); + _dst.enc_ndr_small(uuid.clock_seq_low); + int _uuid_nodes = 6; + int _uuid_nodei = _dst.index; + _dst.advance(1 * _uuid_nodes); + + _dst = _dst.derive(_uuid_nodei); + for (int _i = 0; _i < _uuid_nodes; _i++) { + _dst.enc_ndr_small(uuid.node[_i]); + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + type = (int)_src.dec_ndr_long(); + _src.align(4); + if (uuid == null) { + uuid = new uuid_t(); + } + uuid.time_low = (int)_src.dec_ndr_long(); + uuid.time_mid = (short)_src.dec_ndr_short(); + uuid.time_hi_and_version = (short)_src.dec_ndr_short(); + uuid.clock_seq_hi_and_reserved = (byte)_src.dec_ndr_small(); + uuid.clock_seq_low = (byte)_src.dec_ndr_small(); + int _uuid_nodes = 6; + int _uuid_nodei = _src.index; + _src.advance(1 * _uuid_nodes); + + if (uuid.node == null) { + if (_uuid_nodes < 0 || _uuid_nodes > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + uuid.node = new byte[_uuid_nodes]; + } + _src = _src.derive(_uuid_nodei); + for (int _i = 0; _i < _uuid_nodes; _i++) { + uuid.node[_i] = (byte)_src.dec_ndr_small(); + } + } + } + public static class unicode_string extends NdrObject { + + public short length; + public short maximum_length; + public short[] buffer; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_short(length); + _dst.enc_ndr_short(maximum_length); + _dst.enc_ndr_referent(buffer, 1); + + if (buffer != null) { + _dst = _dst.deferred; + int _bufferl = length / 2; + int _buffers = maximum_length / 2; + _dst.enc_ndr_long(_buffers); + _dst.enc_ndr_long(0); + _dst.enc_ndr_long(_bufferl); + int _bufferi = _dst.index; + _dst.advance(2 * _bufferl); + + _dst = _dst.derive(_bufferi); + for (int _i = 0; _i < _bufferl; _i++) { + _dst.enc_ndr_short(buffer[_i]); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + length = (short)_src.dec_ndr_short(); + maximum_length = (short)_src.dec_ndr_short(); + int _bufferp = _src.dec_ndr_long(); + + if (_bufferp != 0) { + _src = _src.deferred; + int _buffers = _src.dec_ndr_long(); + _src.dec_ndr_long(); + int _bufferl = _src.dec_ndr_long(); + int _bufferi = _src.index; + _src.advance(2 * _bufferl); + + if (buffer == null) { + if (_buffers < 0 || _buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + buffer = new short[_buffers]; + } + _src = _src.derive(_bufferi); + for (int _i = 0; _i < _bufferl; _i++) { + buffer[_i] = (short)_src.dec_ndr_short(); + } + } + } + } + public static class sid_t extends NdrObject { + + public byte revision; + public byte sub_authority_count; + public byte[] identifier_authority; + public int[] sub_authority; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + int _sub_authoritys = sub_authority_count; + _dst.enc_ndr_long(_sub_authoritys); + _dst.enc_ndr_small(revision); + _dst.enc_ndr_small(sub_authority_count); + int _identifier_authoritys = 6; + int _identifier_authorityi = _dst.index; + _dst.advance(1 * _identifier_authoritys); + int _sub_authorityi = _dst.index; + _dst.advance(4 * _sub_authoritys); + + _dst = _dst.derive(_identifier_authorityi); + for (int _i = 0; _i < _identifier_authoritys; _i++) { + _dst.enc_ndr_small(identifier_authority[_i]); + } + _dst = _dst.derive(_sub_authorityi); + for (int _i = 0; _i < _sub_authoritys; _i++) { + _dst.enc_ndr_long(sub_authority[_i]); + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + int _sub_authoritys = _src.dec_ndr_long(); + revision = (byte)_src.dec_ndr_small(); + sub_authority_count = (byte)_src.dec_ndr_small(); + int _identifier_authoritys = 6; + int _identifier_authorityi = _src.index; + _src.advance(1 * _identifier_authoritys); + int _sub_authorityi = _src.index; + _src.advance(4 * _sub_authoritys); + + if (identifier_authority == null) { + if (_identifier_authoritys < 0 || _identifier_authoritys > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + identifier_authority = new byte[_identifier_authoritys]; + } + _src = _src.derive(_identifier_authorityi); + for (int _i = 0; _i < _identifier_authoritys; _i++) { + identifier_authority[_i] = (byte)_src.dec_ndr_small(); + } + if (sub_authority == null) { + if (_sub_authoritys < 0 || _sub_authoritys > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + sub_authority = new int[_sub_authoritys]; + } + _src = _src.derive(_sub_authorityi); + for (int _i = 0; _i < _sub_authoritys; _i++) { + sub_authority[_i] = (int)_src.dec_ndr_long(); + } + } + } +} diff --git a/src/jcifs/http/Handler.java b/src/jcifs/http/Handler.java new file mode 100644 index 0000000..482f822 --- /dev/null +++ b/src/jcifs/http/Handler.java @@ -0,0 +1,159 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.http; + +import java.io.IOException; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; + +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; + +/** + * A URLStreamHandler used to provide NTLM authentication + * capabilities to the default HTTP handler. This acts as a wrapper, + * handling authentication and passing control to the underlying + * stream handler. + */ +public class Handler extends URLStreamHandler { + + /** + * The default HTTP port (80). + */ + public static final int DEFAULT_HTTP_PORT = 80; + + private static final Map PROTOCOL_HANDLERS = new HashMap(); + + private static final String HANDLER_PKGS_PROPERTY = + "java.protocol.handler.pkgs"; + + /** + * Vendor-specific default packages. If no packages are specified in + * "java.protocol.handler.pkgs", the VM uses one or more default + * packages, which are vendor specific. Sun's is included below + * for convenience; others could be as well. If a particular vendor's + * package isn't listed, it can be specified in + * "java.protocol.handler.pkgs". + */ + private static final String[] JVM_VENDOR_DEFAULT_PKGS = new String[] { + "sun.net.www.protocol" + }; + + private static URLStreamHandlerFactory factory; + + /** + * Sets the URL stream handler factory for the environment. This + * allows specification of the factory used in creating underlying + * stream handlers. This can be called once per JVM instance. + * + * @param factory The URL stream handler factory. + */ + public static void setURLStreamHandlerFactory( + URLStreamHandlerFactory factory) { + synchronized (PROTOCOL_HANDLERS) { + if (Handler.factory != null) { + throw new IllegalStateException( + "URLStreamHandlerFactory already set."); + } + PROTOCOL_HANDLERS.clear(); + Handler.factory = factory; + } + } + + /** + * Returns the default HTTP port. + * + * @return An int containing the default HTTP port. + */ + protected int getDefaultPort() { + return DEFAULT_HTTP_PORT; + } + + protected URLConnection openConnection(URL url) throws IOException { + url = new URL(url, url.toExternalForm(), + getDefaultStreamHandler(url.getProtocol())); + return new NtlmHttpURLConnection((HttpURLConnection) + url.openConnection()); + } + + private static URLStreamHandler getDefaultStreamHandler(String protocol) + throws IOException { + synchronized (PROTOCOL_HANDLERS) { + URLStreamHandler handler = (URLStreamHandler) + PROTOCOL_HANDLERS.get(protocol); + if (handler != null) return handler; + if (factory != null) { + handler = factory.createURLStreamHandler(protocol); + } + if (handler == null) { + String path = System.getProperty(HANDLER_PKGS_PROPERTY); + StringTokenizer tokenizer = new StringTokenizer(path, "|"); + while (tokenizer.hasMoreTokens()) { + String provider = tokenizer.nextToken().trim(); + if (provider.equals("jcifs")) continue; + String className = provider + "." + protocol + ".Handler"; + try { + Class handlerClass = null; + try { + handlerClass = Class.forName(className); + } catch (Exception ex) { } + if (handlerClass == null) { + handlerClass = ClassLoader.getSystemClassLoader( + ).loadClass(className); + } + handler = (URLStreamHandler) handlerClass.newInstance(); + break; + } catch (Exception ex) { } + } + } + if (handler == null) { + for (int i = 0; i < JVM_VENDOR_DEFAULT_PKGS.length; i++) { + String className = JVM_VENDOR_DEFAULT_PKGS[i] + "." + + protocol + ".Handler"; + try { + Class handlerClass = null; + try { + handlerClass = Class.forName(className); + } catch (Exception ex) { } + if (handlerClass == null) { + handlerClass = ClassLoader.getSystemClassLoader( + ).loadClass(className); + } + handler = (URLStreamHandler) handlerClass.newInstance(); + } catch (Exception ex) { } + if (handler != null) break; + } + } + if (handler == null) { + throw new IOException( + "Unable to find default handler for protocol: " + + protocol); + } + PROTOCOL_HANDLERS.put(protocol, handler); + return handler; + } + } + +} diff --git a/src/jcifs/http/NetworkExplorer.java b/src/jcifs/http/NetworkExplorer.java new file mode 100644 index 0000000..9383488 --- /dev/null +++ b/src/jcifs/http/NetworkExplorer.java @@ -0,0 +1,536 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.http; + +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; +import java.util.*; +import java.text.SimpleDateFormat; +import java.net.UnknownHostException; +import jcifs.*; +import jcifs.http.*; +import jcifs.smb.*; +import jcifs.netbios.NbtAddress; +import jcifs.util.MimeMap; +import jcifs.util.Base64; +import jcifs.util.LogStream; + +/** + * This servlet may be used to "browse" the entire hierarchy of resources + * on an SMB network like one might with Network Neighborhood or Windows + * Explorer. The users credentials with be negotiated using NTLM SSP if + * the client is Microsoft Internet Explorer. + */ + +public class NetworkExplorer extends HttpServlet { + + private static LogStream log = LogStream.getInstance(); + + private MimeMap mimeMap; + private String style; + private NtlmSsp ntlmSsp; + private boolean credentialsSupplied; + private boolean enableBasic; + private boolean insecureBasic; + private String realm, defaultDomain; + + public void init() throws ServletException { + InputStream is; + StringBuffer sb = new StringBuffer(); + byte[] buf = new byte[1024]; + int n, level; + String name; + + Config.setProperty( "jcifs.smb.client.soTimeout", "600000" ); + Config.setProperty( "jcifs.smb.client.attrExpirationPeriod", "300000" ); + + Enumeration e = getInitParameterNames(); + while( e.hasMoreElements() ) { + name = (String)e.nextElement(); + if( name.startsWith( "jcifs." )) { + Config.setProperty( name, getInitParameter( name )); + } + } + + if( Config.getProperty( "jcifs.smb.client.username" ) == null ) { + ntlmSsp = new NtlmSsp(); + } else { + credentialsSupplied = true; + } + + try { + mimeMap = new MimeMap(); + is = getClass().getClassLoader().getResourceAsStream( "jcifs/http/ne.css" ); + while(( n = is.read( buf )) != -1 ) { + sb.append( new String( buf, 0, n, "ISO8859_1" )); + } + style = sb.toString(); + } catch( IOException ioe ) { + throw new ServletException( ioe.getMessage() ); + } + + enableBasic = Config.getBoolean("jcifs.http.enableBasic", false ); + insecureBasic = Config.getBoolean("jcifs.http.insecureBasic", false ); + realm = Config.getProperty("jcifs.http.basicRealm"); + if (realm == null) realm = "jCIFS"; + defaultDomain = Config.getProperty("jcifs.smb.client.domain"); + + if(( level = Config.getInt( "jcifs.util.loglevel", -1 )) != -1 ) { + LogStream.setLevel( level ); + } + if( log.level > 2 ) { + try { + Config.store( log, "JCIFS PROPERTIES" ); + } catch( IOException ioe ) { + } + } + } + + protected void doFile( HttpServletRequest req, + HttpServletResponse resp, SmbFile file ) throws IOException { + byte[] buf = new byte[8192]; + SmbFileInputStream in; + ServletOutputStream out; + String url, type; + int n; + + in = new SmbFileInputStream( file ); + out = resp.getOutputStream(); + url = file.getPath(); + + resp.setContentType( "text/plain" ); + + if(( n = url.lastIndexOf( '.' )) > 0 && + ( type = url.substring( n + 1 )) != null && + type.length() > 1 && type.length() < 6 ) { + resp.setContentType( mimeMap.getMimeType( type )); + } + resp.setHeader( "Content-Length", file.length() + "" ); + resp.setHeader( "Accept-Ranges", "Bytes" ); + + while(( n = in.read( buf )) != -1 ) { + out.write( buf, 0, n ); + } + } + protected int compareNames( SmbFile f1, String f1name, SmbFile f2 ) throws IOException { + if( f1.isDirectory() != f2.isDirectory() ) { + return f1.isDirectory() ? -1 : 1; + } + return f1name.compareToIgnoreCase( f2.getName() ); + } + protected int compareSizes( SmbFile f1, String f1name, SmbFile f2 ) throws IOException { + long diff; + + if( f1.isDirectory() != f2.isDirectory() ) { + return f1.isDirectory() ? -1 : 1; + } + if( f1.isDirectory() ) { + return f1name.compareToIgnoreCase( f2.getName() ); + } + diff = f1.length() - f2.length(); + if( diff == 0 ) { + return f1name.compareToIgnoreCase( f2.getName() ); + } + return diff > 0 ? -1 : 1; + } + protected int compareTypes( SmbFile f1, String f1name, SmbFile f2 ) throws IOException { + String f2name, t1, t2; + int i; + + if( f1.isDirectory() != f2.isDirectory() ) { + return f1.isDirectory() ? -1 : 1; + } + f2name = f2.getName(); + if( f1.isDirectory() ) { + return f1name.compareToIgnoreCase( f2name ); + } + i = f1name.lastIndexOf( '.' ); + t1 = i == -1 ? "" : f1name.substring( i + 1 ); + i = f2name.lastIndexOf( '.' ); + t2 = i == -1 ? "" : f2name.substring( i + 1 ); + + i = t1.compareToIgnoreCase( t2 ); + if( i == 0 ) { + return f1name.compareToIgnoreCase( f2name ); + } + return i; + } + protected int compareDates( SmbFile f1, String f1name, SmbFile f2 ) throws IOException { + if( f1.isDirectory() != f2.isDirectory() ) { + return f1.isDirectory() ? -1 : 1; + } + if( f1.isDirectory() ) { + return f1name.compareToIgnoreCase( f2.getName() ); + } + return f1.lastModified() > f2.lastModified() ? -1 : 1; + } + protected void doDirectory( HttpServletRequest req, HttpServletResponse resp, SmbFile dir ) throws IOException { + PrintWriter out; + SmbFile[] dirents; + SmbFile f; + int i, j, len, maxLen, dirCount, fileCount, sort; + String str, name, path, fmt; + LinkedList sorted; + ListIterator iter; + SimpleDateFormat sdf = new SimpleDateFormat( "MM/d/yy h:mm a" ); + GregorianCalendar cal = new GregorianCalendar(); + + sdf.setCalendar( cal ); + + dirents = dir.listFiles(); + if( log.level > 2 ) + log.println( dirents.length + " items listed" ); + sorted = new LinkedList(); + if(( fmt = req.getParameter( "fmt" )) == null ) { + fmt = "col"; + } + sort = 0; + if(( str = req.getParameter( "sort" )) == null || str.equals( "name" )) { + sort = 0; + } else if( str.equals( "size" )) { + sort = 1; + } else if( str.equals( "type" )) { + sort = 2; + } else if( str.equals( "date" )) { + sort = 3; + } + dirCount = fileCount = 0; + maxLen = 28; + for( i = 0; i < dirents.length; i++ ) { + try { + if( dirents[i].getType() == SmbFile.TYPE_NAMED_PIPE ) { + continue; + } + } catch( SmbAuthException sae ) { + if( log.level > 2 ) + sae.printStackTrace( log ); + } catch( SmbException se ) { + if( log.level > 2 ) + se.printStackTrace( log ); + if( se.getNtStatus() != se.NT_STATUS_UNSUCCESSFUL ) { + throw se; + } + } + if( dirents[i].isDirectory() ) { + dirCount++; + } else { + fileCount++; + } + + name = dirents[i].getName(); + if( log.level > 3 ) + log.println( i + ": " + name ); + len = name.length(); + if( len > maxLen ) { + maxLen = len; + } + + iter = sorted.listIterator(); + for( j = 0; iter.hasNext(); j++ ) { + if( sort == 0 ) { + if( compareNames( dirents[i], name, (SmbFile)iter.next() ) < 0 ) { + break; + } + } else if( sort == 1 ) { + if( compareSizes( dirents[i], name, (SmbFile)iter.next() ) < 0 ) { + break; + } + } else if( sort == 2 ) { + if( compareTypes( dirents[i], name, (SmbFile)iter.next() ) < 0 ) { + break; + } + } else if( sort == 3 ) { + if( compareDates( dirents[i], name, (SmbFile)iter.next() ) < 0 ) { + break; + } + } + } + sorted.add( j, dirents[i] ); + } + if( maxLen > 50 ) { + maxLen = 50; + } + maxLen *= 9; /* convert to px */ + + out = resp.getWriter(); + + resp.setContentType( "text/html" ); + + out.println( "" ); + out.println( "Network Explorer" ); + out.println( "" ); + out.println( "" ); + out.println( "" ); + + out.print( "Name" ); + out.println( "Size" ); + out.println( "Type" ); + out.println( "Modified

" ); + + path = dir.getCanonicalPath(); + + if( path.length() < 7 ) { + out.println( "smb://
" ); + path = "."; + } else { + out.println( "" + path + "
" ); + path = "../"; + } + out.println( (dirCount + fileCount) + " objects (" + dirCount + " directories, " + fileCount + " files)
" ); + out.println( "normal | detailed" ); + out.println( "

" ); + + out.print( "" ); + if( fmt.equals( "detail" )) { + out.println( "
" ); + } + + if( path.length() == 1 || dir.getType() != SmbFile.TYPE_WORKGROUP ) { + path = ""; + } + + iter = sorted.listIterator(); + while( iter.hasNext() ) { + f = (SmbFile)iter.next(); + name = f.getName(); + + if( fmt.equals( "detail" )) { + out.print( "" ); + out.print( name ); + out.print( "" ); + } else { + out.print( "\">" ); + out.print( name ); + out.print( "
" ); + out.print( (f.length() / 1024) + " KB
" ); + i = name.lastIndexOf( '.' ) + 1; + if( i > 1 && (name.length() - i) < 6 ) { + out.print( name.substring( i ).toUpperCase() + "
" ); + } else { + out.print( " " ); + } + out.print( "
" ); + out.print( sdf.format( new Date( f.lastModified() ))); + out.print( "
" ); + } + out.println( "
" ); + } else { + out.print( "" ); + out.print( name ); + out.print( "" ); + } else { + out.print( ";\" HREF=\"" ); + out.print( path ); + out.print( name ); + out.print( "\">" ); + out.print( name ); + out.print( "
" ); + out.print( (f.length() / 1024) + "KB
" ); + out.print( sdf.format( new Date( f.lastModified() ))); + out.print( "
" ); + out.println( "" ); + } + } + } + + out.println( "
" ); + out.println( "" ); + out.close(); + } + private String parseServerAndShare( String pathInfo ) { + char[] out = new char[256]; + char ch; + int len, p, i; + + if( pathInfo == null ) { + return null; + } + len = pathInfo.length(); + + p = i = 0; + while( p < len && pathInfo.charAt( p ) == '/' ) { + p++; + } + if( p == len ) { + return null; + } + + /* collect server name */ + while ( p < len && ( ch = pathInfo.charAt( p )) != '/' ) { + out[i++] = ch; + p++; + } + while( p < len && pathInfo.charAt( p ) == '/' ) { + p++; + } + if( p < len ) { /* then there must be a share */ + out[i++] = '/'; + do { /* collect the share name */ + out[i++] = (ch = pathInfo.charAt( p++ )); + } while( p < len && ch != '/' ); + } + return new String( out, 0, i ); + } + public void doGet( HttpServletRequest req, + HttpServletResponse resp ) throws IOException, ServletException { + UniAddress dc; + String msg, pathInfo, server = null; + boolean offerBasic, possibleWorkgroup = true; + NtlmPasswordAuthentication ntlm = null; + HttpSession ssn = req.getSession( false ); + + if(( pathInfo = req.getPathInfo() ) != null ) { + int i; + server = parseServerAndShare( pathInfo ); + if( server != null && ( i = server.indexOf( '/' )) > 0 ) { + server = server.substring( 0, i ).toLowerCase(); + possibleWorkgroup = false; + } + } + + msg = req.getHeader( "Authorization" ); + offerBasic = enableBasic && (insecureBasic || req.isSecure()); + + if( msg != null && (msg.startsWith( "NTLM " ) || + (offerBasic && msg.startsWith("Basic ")))) { + + if( msg.startsWith("NTLM ")) { + byte[] challenge; + + if( pathInfo == null || server == null ) { + String mb = NbtAddress.getByName( NbtAddress.MASTER_BROWSER_NAME, 0x01, null ).getHostAddress(); + dc = UniAddress.getByName( mb ); + } else { + dc = UniAddress.getByName( server, possibleWorkgroup ); + } + + req.getSession(); /* ensure session id is set for cluster env. */ + challenge = SmbSession.getChallenge( dc ); + if(( ntlm = NtlmSsp.authenticate( req, resp, challenge )) == null ) { + return; + } + } else { /* Basic */ + String auth = new String( Base64.decode( msg.substring(6) ), "US-ASCII" ); + int index = auth.indexOf( ':' ); + String user = (index != -1) ? auth.substring(0, index) : auth; + String password = (index != -1) ? auth.substring(index + 1) : ""; + index = user.indexOf('\\'); + if (index == -1) index = user.indexOf('/'); + String domain = (index != -1) ? user.substring(0, index) : defaultDomain; + user = (index != -1) ? user.substring(index + 1) : user; + ntlm = new NtlmPasswordAuthentication(domain, user, password); + } + + req.getSession().setAttribute( "npa-" + server, ntlm ); + + } else if( !credentialsSupplied ) { + if( ssn != null ) { + ntlm = (NtlmPasswordAuthentication)ssn.getAttribute( "npa-" + server ); + } + if( ntlm == null ) { + resp.setHeader( "WWW-Authenticate", "NTLM" ); + if (offerBasic) { + resp.addHeader( "WWW-Authenticate", "Basic realm=\"" + realm + "\""); + } + resp.setHeader( "Connection", "close" ); + resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED ); + resp.flushBuffer(); + return; + } + } + + try { + SmbFile file; + + if( ntlm != null ) { + file = new SmbFile( "smb:/" + pathInfo , ntlm ); + } else if( server == null ) { + file = new SmbFile( "smb://" ); + } else { + file = new SmbFile( "smb:/" + pathInfo ); + } + + if( file.isDirectory() ) { + doDirectory( req, resp, file ); + } else { + doFile( req, resp, file ); + } + } catch( SmbAuthException sae ) { + if( ssn != null ) { + ssn.removeAttribute( "npa-" + server ); + } + if( sae.getNtStatus() == sae.NT_STATUS_ACCESS_VIOLATION ) { + /* Server challenge no longer valid for + * externally supplied password hashes. + */ + resp.sendRedirect( req.getRequestURL().toString() ); + return; + } + resp.setHeader( "WWW-Authenticate", "NTLM" ); + if (offerBasic) { + resp.addHeader( "WWW-Authenticate", "Basic realm=\"" + realm + "\""); + } + resp.setHeader( "Connection", "close" ); + resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED ); + resp.flushBuffer(); + return; + } catch( DfsReferral dr ) { + StringBuffer redir = req.getRequestURL(); + String qs = req.getQueryString(); + redir = new StringBuffer( redir.substring( 0, redir.length() - req.getPathInfo().length() )); + redir.append( '/' ); + redir.append(dr.server); + redir.append( '/' ); + redir.append(dr.share); + redir.append( '/' ); + if( qs != null ) { + redir.append( req.getQueryString() ); + } + resp.sendRedirect( redir.toString() ); + resp.flushBuffer(); + return; + } + } +} + diff --git a/src/jcifs/http/NtlmHttpFilter.java b/src/jcifs/http/NtlmHttpFilter.java new file mode 100644 index 0000000..936ad57 --- /dev/null +++ b/src/jcifs/http/NtlmHttpFilter.java @@ -0,0 +1,254 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Jason Pugsley" + * "skeetz" + * "Eric Glass" + * and Marcel, Thomas, ... + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.http; + +import java.io.*; +import java.util.Enumeration; +import java.net.UnknownHostException; +import javax.servlet.*; +import javax.servlet.http.*; +import jcifs.*; +import jcifs.smb.SmbSession; +import jcifs.smb.NtlmChallenge; +import jcifs.smb.NtlmPasswordAuthentication; +import jcifs.smb.SmbAuthException; +import jcifs.util.Base64; +import jcifs.util.LogStream; +import jcifs.netbios.NbtAddress; + +/** + * This servlet Filter can be used to negotiate password hashes with + * MSIE clients using NTLM SSP. This is similar to Authentication: + * BASIC but weakly encrypted and without requiring the user to re-supply + * authentication credentials. + *

+ * Read jCIFS NTLM HTTP Authentication and the Network Explorer Servlet for complete details. + */ + +public class NtlmHttpFilter implements Filter { + + private static LogStream log = LogStream.getInstance(); + + private String defaultDomain; + private String domainController; + private boolean loadBalance; + private boolean enableBasic; + private boolean insecureBasic; + private String realm; + + public void init( FilterConfig filterConfig ) throws ServletException { + String name; + int level; + + /* Set jcifs properties we know we want; soTimeout and cachePolicy to 30min. + */ + Config.setProperty( "jcifs.smb.client.soTimeout", "1800000" ); + Config.setProperty( "jcifs.netbios.cachePolicy", "1200" ); + /* The Filter can only work with NTLMv1 as it uses a man-in-the-middle + * techinque that NTLMv2 specifically thwarts. A real NTLM Filter would + * need to do a NETLOGON RPC that JCIFS will likely never implement + * because it requires a lot of extra crypto not used by CIFS. + */ + Config.setProperty( "jcifs.smb.lmCompatibility", "0" ); + Config.setProperty( "jcifs.smb.client.useExtendedSecurity", "false" ); + + Enumeration e = filterConfig.getInitParameterNames(); + while( e.hasMoreElements() ) { + name = (String)e.nextElement(); + if( name.startsWith( "jcifs." )) { + Config.setProperty( name, filterConfig.getInitParameter( name )); + } + } + defaultDomain = Config.getProperty("jcifs.smb.client.domain"); + domainController = Config.getProperty( "jcifs.http.domainController" ); + if( domainController == null ) { + domainController = defaultDomain; + loadBalance = Config.getBoolean( "jcifs.http.loadBalance", true ); + } + enableBasic = Boolean.valueOf( + Config.getProperty("jcifs.http.enableBasic")).booleanValue(); + insecureBasic = Boolean.valueOf( + Config.getProperty("jcifs.http.insecureBasic")).booleanValue(); + realm = Config.getProperty("jcifs.http.basicRealm"); + if (realm == null) realm = "jCIFS"; + + if(( level = Config.getInt( "jcifs.util.loglevel", -1 )) != -1 ) { + LogStream.setLevel( level ); + } + if( log.level > 2 ) { + try { + Config.store( log, "JCIFS PROPERTIES" ); + } catch( IOException ioe ) { + } + } + } + + public void destroy() { + } + + /** + * This method simply calls negotiate( req, resp, false ) + * and then chain.doFilter. You can override and call + * negotiate manually to achive a variety of different behavior. + */ + public void doFilter( ServletRequest request, + ServletResponse response, + FilterChain chain ) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest)request; + HttpServletResponse resp = (HttpServletResponse)response; + NtlmPasswordAuthentication ntlm; + + if ((ntlm = negotiate( req, resp, false )) == null) { + return; + } + + chain.doFilter( new NtlmHttpServletRequest( req, ntlm ), response ); + } + + /** + * Negotiate password hashes with MSIE clients using NTLM SSP + * @param req The servlet request + * @param resp The servlet response + * @param skipAuthentication If true the negotiation is only done if it is + * initiated by the client (MSIE post requests after successful NTLM SSP + * authentication). If false and the user has not been authenticated yet + * the client will be forced to send an authentication (server sends + * HttpServletResponse.SC_UNAUTHORIZED). + * @return True if the negotiation is complete, otherwise false + */ + protected NtlmPasswordAuthentication negotiate( HttpServletRequest req, + HttpServletResponse resp, + boolean skipAuthentication ) throws IOException, ServletException { + UniAddress dc; + String msg; + NtlmPasswordAuthentication ntlm = null; + msg = req.getHeader( "Authorization" ); + boolean offerBasic = enableBasic && (insecureBasic || req.isSecure()); + + if( msg != null && (msg.startsWith( "NTLM " ) || + (offerBasic && msg.startsWith("Basic ")))) { + if (msg.startsWith("NTLM ")) { + HttpSession ssn = req.getSession(); + byte[] challenge; + + if( loadBalance ) { + NtlmChallenge chal = (NtlmChallenge)ssn.getAttribute( "NtlmHttpChal" ); + if( chal == null ) { + chal = SmbSession.getChallengeForDomain(); + ssn.setAttribute( "NtlmHttpChal", chal ); + } + dc = chal.dc; + challenge = chal.challenge; + } else { + dc = UniAddress.getByName( domainController, true ); + challenge = SmbSession.getChallenge( dc ); + } + + if(( ntlm = NtlmSsp.authenticate( req, resp, challenge )) == null ) { + return null; + } + /* negotiation complete, remove the challenge object */ + ssn.removeAttribute( "NtlmHttpChal" ); + } else { + String auth = new String(Base64.decode(msg.substring(6)), + "US-ASCII"); + int index = auth.indexOf(':'); + String user = (index != -1) ? auth.substring(0, index) : auth; + String password = (index != -1) ? auth.substring(index + 1) : + ""; + index = user.indexOf('\\'); + if (index == -1) index = user.indexOf('/'); + String domain = (index != -1) ? user.substring(0, index) : + defaultDomain; + user = (index != -1) ? user.substring(index + 1) : user; + ntlm = new NtlmPasswordAuthentication(domain, user, password); + dc = UniAddress.getByName( domainController, true ); + } + try { + + SmbSession.logon( dc, ntlm ); + + if( log.level > 2 ) { + log.println( "NtlmHttpFilter: " + ntlm + + " successfully authenticated against " + dc ); + } + } catch( SmbAuthException sae ) { + if( log.level > 1 ) { + log.println( "NtlmHttpFilter: " + ntlm.getName() + + ": 0x" + jcifs.util.Hexdump.toHexString( sae.getNtStatus(), 8 ) + + ": " + sae ); + } + if( sae.getNtStatus() == sae.NT_STATUS_ACCESS_VIOLATION ) { + /* Server challenge no longer valid for + * externally supplied password hashes. + */ + HttpSession ssn = req.getSession(false); + if (ssn != null) { + ssn.removeAttribute( "NtlmHttpAuth" ); + } + } + resp.setHeader( "WWW-Authenticate", "NTLM" ); + if (offerBasic) { + resp.addHeader( "WWW-Authenticate", "Basic realm=\"" + + realm + "\""); + } + resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED ); + resp.setContentLength(0); /* Marcel Feb-15-2005 */ + resp.flushBuffer(); + return null; + } + req.getSession().setAttribute( "NtlmHttpAuth", ntlm ); + } else { + if (!skipAuthentication) { + HttpSession ssn = req.getSession(false); + if (ssn == null || (ntlm = (NtlmPasswordAuthentication) + ssn.getAttribute("NtlmHttpAuth")) == null) { + resp.setHeader( "WWW-Authenticate", "NTLM" ); + if (offerBasic) { + resp.addHeader( "WWW-Authenticate", "Basic realm=\"" + + realm + "\""); + } + resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED ); + resp.setContentLength(0); + resp.flushBuffer(); + return null; + } + } + } + + return ntlm; + } + + // Added by cgross to work with weblogic 6.1. + public void setFilterConfig( FilterConfig f ) { + try { + init( f ); + } catch( Exception e ) { + e.printStackTrace(); + } + } + public FilterConfig getFilterConfig() { + return null; + } +} + diff --git a/src/jcifs/http/NtlmHttpServletRequest.java b/src/jcifs/http/NtlmHttpServletRequest.java new file mode 100644 index 0000000..a6746be --- /dev/null +++ b/src/jcifs/http/NtlmHttpServletRequest.java @@ -0,0 +1,44 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.http; + +import java.security.Principal; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +class NtlmHttpServletRequest extends HttpServletRequestWrapper { + + Principal principal; + + NtlmHttpServletRequest( HttpServletRequest req, Principal principal ) { + super( req ); + this.principal = principal; + } + public String getRemoteUser() { + return principal.getName(); + } + public Principal getUserPrincipal() { + return principal; + } + public String getAuthType() { + return "NTLM"; + } +} + diff --git a/src/jcifs/http/NtlmHttpURLConnection.java b/src/jcifs/http/NtlmHttpURLConnection.java new file mode 100644 index 0000000..3c95371 --- /dev/null +++ b/src/jcifs/http/NtlmHttpURLConnection.java @@ -0,0 +1,633 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.http; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; + +import java.net.Authenticator; +import java.net.HttpURLConnection; +import java.net.PasswordAuthentication; +import java.net.ProtocolException; +import java.net.URL; +import java.net.URLDecoder; + +import java.security.Permission; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import jcifs.Config; + +import jcifs.ntlmssp.NtlmFlags; +import jcifs.ntlmssp.NtlmMessage; +import jcifs.ntlmssp.Type1Message; +import jcifs.ntlmssp.Type2Message; +import jcifs.ntlmssp.Type3Message; + +import jcifs.util.Base64; + +/** + * Wraps an HttpURLConnection to provide NTLM authentication + * services. + * + * Please read Using jCIFS NTLM Authentication for HTTP Connections. + */ +public class NtlmHttpURLConnection extends HttpURLConnection { + + private static final int MAX_REDIRECTS = + Integer.parseInt(System.getProperty("http.maxRedirects", "20")); + + private static final int LM_COMPATIBILITY = + Config.getInt("jcifs.smb.lmCompatibility", 0); + + private static final String DEFAULT_DOMAIN; + + private HttpURLConnection connection; + + private Map requestProperties; + + private Map headerFields; + + private ByteArrayOutputStream cachedOutput; + + private String authProperty; + + private String authMethod; + + private boolean handshakeComplete; + + static { + String domain = System.getProperty("http.auth.ntlm.domain"); + if (domain == null) domain = Type3Message.getDefaultDomain(); + DEFAULT_DOMAIN = domain; + } + + public NtlmHttpURLConnection(HttpURLConnection connection) { + super(connection.getURL()); + this.connection = connection; + requestProperties = new HashMap(); + } + + public void connect() throws IOException { + if (connected) return; + connection.connect(); + connected = true; + } + + private void handshake() throws IOException { + if (handshakeComplete) return; + doHandshake(); + handshakeComplete = true; + } + + public URL getURL() { + return connection.getURL(); + } + + public int getContentLength() { + try { + handshake(); + } catch (IOException ex) { } + return connection.getContentLength(); + } + + public String getContentType() { + try { + handshake(); + } catch (IOException ex) { } + return connection.getContentType(); + } + + public String getContentEncoding() { + try { + handshake(); + } catch (IOException ex) { } + return connection.getContentEncoding(); + } + + public long getExpiration() { + try { + handshake(); + } catch (IOException ex) { } + return connection.getExpiration(); + } + + public long getDate() { + try { + handshake(); + } catch (IOException ex) { } + return connection.getDate(); + } + + public long getLastModified() { + try { + handshake(); + } catch (IOException ex) { } + return connection.getLastModified(); + } + + public String getHeaderField(String header) { + try { + handshake(); + } catch (IOException ex) { } + return connection.getHeaderField(header); + } + + private Map getHeaderFields0() { + if (headerFields != null) return headerFields; + Map map = new HashMap(); + String key = connection.getHeaderFieldKey(0); + String value = connection.getHeaderField(0); + for (int i = 1; key != null || value != null; i++) { + List values = (List) map.get(key); + if (values == null) { + values = new ArrayList(); + map.put(key, values); + } + values.add(value); + key = connection.getHeaderFieldKey(i); + value = connection.getHeaderField(i); + } + Iterator entries = map.entrySet().iterator(); + while (entries.hasNext()) { + Map.Entry entry = (Map.Entry) entries.next(); + entry.setValue(Collections.unmodifiableList((List) + entry.getValue())); + } + return (headerFields = Collections.unmodifiableMap(map)); + } + + public Map getHeaderFields() { + if (headerFields != null) return headerFields; + try { + handshake(); + } catch (IOException ex) { } + return getHeaderFields0(); + } + + public int getHeaderFieldInt(String header, int def) { + try { + handshake(); + } catch (IOException ex) { } + return connection.getHeaderFieldInt(header, def); + } + + public long getHeaderFieldDate(String header, long def) { + try { + handshake(); + } catch (IOException ex) { } + return connection.getHeaderFieldDate(header, def); + } + + public String getHeaderFieldKey(int index) { + try { + handshake(); + } catch (IOException ex) { } + return connection.getHeaderFieldKey(index); + } + + public String getHeaderField(int index) { + try { + handshake(); + } catch (IOException ex) { } + return connection.getHeaderField(index); + } + + public Object getContent() throws IOException { + try { + handshake(); + } catch (IOException ex) { } + return connection.getContent(); + } + + public Object getContent(Class[] classes) throws IOException { + try { + handshake(); + } catch (IOException ex) { } + return connection.getContent(classes); + } + + public Permission getPermission() throws IOException { + return connection.getPermission(); + } + + public InputStream getInputStream() throws IOException { + try { + handshake(); + } catch (IOException ex) { } + return connection.getInputStream(); + } + + public OutputStream getOutputStream() throws IOException { + try { + connect(); + } catch (IOException ex) { } + OutputStream output = connection.getOutputStream(); + cachedOutput = new ByteArrayOutputStream(); + return new CacheStream(output, cachedOutput); + } + + public String toString() { + return connection.toString(); + } + + public void setDoInput(boolean doInput) { + connection.setDoInput(doInput); + this.doInput = doInput; + } + + public boolean getDoInput() { + return connection.getDoInput(); + } + + public void setDoOutput(boolean doOutput) { + connection.setDoOutput(doOutput); + this.doOutput = doOutput; + } + + public boolean getDoOutput() { + return connection.getDoOutput(); + } + + public void setAllowUserInteraction(boolean allowUserInteraction) { + connection.setAllowUserInteraction(allowUserInteraction); + this.allowUserInteraction = allowUserInteraction; + } + + public boolean getAllowUserInteraction() { + return connection.getAllowUserInteraction(); + } + + public void setUseCaches(boolean useCaches) { + connection.setUseCaches(useCaches); + this.useCaches = useCaches; + } + + public boolean getUseCaches() { + return connection.getUseCaches(); + } + + public void setIfModifiedSince(long ifModifiedSince) { + connection.setIfModifiedSince(ifModifiedSince); + this.ifModifiedSince = ifModifiedSince; + } + + public long getIfModifiedSince() { + return connection.getIfModifiedSince(); + } + + public boolean getDefaultUseCaches() { + return connection.getDefaultUseCaches(); + } + + public void setDefaultUseCaches(boolean defaultUseCaches) { + connection.setDefaultUseCaches(defaultUseCaches); + } + + public void setRequestProperty(String key, String value) { + if (key == null) throw new NullPointerException(); + List values = new ArrayList(); + values.add(value); + boolean found = false; + Iterator entries = requestProperties.entrySet().iterator(); + while (entries.hasNext()) { + Map.Entry entry = (Map.Entry) entries.next(); + if (key.equalsIgnoreCase((String) entry.getKey())) { + entry.setValue(values); + found = true; + break; + } + } + if (!found) requestProperties.put(key, values); + connection.setRequestProperty(key, value); + } + + public void addRequestProperty(String key, String value) { + if (key == null) throw new NullPointerException(); + List values = null; + Iterator entries = requestProperties.entrySet().iterator(); + while (entries.hasNext()) { + Map.Entry entry = (Map.Entry) entries.next(); + if (key.equalsIgnoreCase((String) entry.getKey())) { + values = (List) entry.getValue(); + values.add(value); + break; + } + } + if (values == null) { + values = new ArrayList(); + values.add(value); + requestProperties.put(key, values); + } + // 1.3-compatible. + StringBuffer buffer = new StringBuffer(); + Iterator propertyValues = values.iterator(); + while (propertyValues.hasNext()) { + buffer.append(propertyValues.next()); + if (propertyValues.hasNext()) { + buffer.append(", "); + } + } + connection.setRequestProperty(key, buffer.toString()); + } + + public String getRequestProperty(String key) { + return connection.getRequestProperty(key); + } + + public Map getRequestProperties() { + Map map = new HashMap(); + Iterator entries = requestProperties.entrySet().iterator(); + while (entries.hasNext()) { + Map.Entry entry = (Map.Entry) entries.next(); + map.put(entry.getKey(), + Collections.unmodifiableList((List) entry.getValue())); + } + return Collections.unmodifiableMap(map); + } + + public void setInstanceFollowRedirects(boolean instanceFollowRedirects) { + connection.setInstanceFollowRedirects(instanceFollowRedirects); + } + + public boolean getInstanceFollowRedirects() { + return connection.getInstanceFollowRedirects(); + } + + public void setRequestMethod(String requestMethod) + throws ProtocolException { + connection.setRequestMethod(requestMethod); + this.method = requestMethod; + } + + public String getRequestMethod() { + return connection.getRequestMethod(); + } + + public int getResponseCode() throws IOException { + try { + handshake(); + } catch (IOException ex) { } + return connection.getResponseCode(); + } + + public String getResponseMessage() throws IOException { + try { + handshake(); + } catch (IOException ex) { } + return connection.getResponseMessage(); + } + + public void disconnect() { + connection.disconnect(); + handshakeComplete = false; + connected = false; + } + + public boolean usingProxy() { + return connection.usingProxy(); + } + + public InputStream getErrorStream() { + try { + handshake(); + } catch (IOException ex) { } + return connection.getErrorStream(); + } + + private int parseResponseCode() throws IOException { + try { + String response = connection.getHeaderField(0); + int index = response.indexOf(' '); + while (response.charAt(index) == ' ') index++; + return Integer.parseInt(response.substring(index, index + 3)); + } catch (Exception ex) { + throw new IOException(ex.getMessage()); + } + } + + private void doHandshake() throws IOException { + connect(); + try { + int response = parseResponseCode(); + if (response != HTTP_UNAUTHORIZED && response != HTTP_PROXY_AUTH) { + return; + } + Type1Message type1 = (Type1Message) attemptNegotiation(response); + if (type1 == null) return; // no NTLM + int attempt = 0; + while (attempt < MAX_REDIRECTS) { + connection.setRequestProperty(authProperty, authMethod + ' ' + + Base64.encode(type1.toByteArray())); + connection.connect(); // send type 1 + response = parseResponseCode(); + if (response != HTTP_UNAUTHORIZED && + response != HTTP_PROXY_AUTH) { + return; + } + Type3Message type3 = (Type3Message) + attemptNegotiation(response); + if (type3 == null) return; + connection.setRequestProperty(authProperty, authMethod + ' ' + + Base64.encode(type3.toByteArray())); + connection.connect(); // send type 3 + if (cachedOutput != null && doOutput) { + OutputStream output = connection.getOutputStream(); + cachedOutput.writeTo(output); + output.flush(); + } + response = parseResponseCode(); + if (response != HTTP_UNAUTHORIZED && + response != HTTP_PROXY_AUTH) { + return; + } + attempt++; + if (allowUserInteraction && attempt < MAX_REDIRECTS) { + reconnect(); + } else { + break; + } + } + throw new IOException("Unable to negotiate NTLM authentication."); + } finally { + cachedOutput = null; + } + } + + private NtlmMessage attemptNegotiation(int response) throws IOException { + authProperty = null; + authMethod = null; + InputStream errorStream = connection.getErrorStream(); + if (errorStream != null && errorStream.available() != 0) { + int count; + byte[] buf = new byte[1024]; + while ((count = errorStream.read(buf, 0, 1024)) != -1); + } + String authHeader; + if (response == HTTP_UNAUTHORIZED) { + authHeader = "WWW-Authenticate"; + authProperty = "Authorization"; + } else { + authHeader = "Proxy-Authenticate"; + authProperty = "Proxy-Authorization"; + } + String authorization = null; + List methods = (List) getHeaderFields0().get(authHeader); + if (methods == null) return null; + Iterator iterator = methods.iterator(); + while (iterator.hasNext()) { + String currentAuthMethod = (String) iterator.next(); + if (currentAuthMethod.startsWith("NTLM")) { + if (currentAuthMethod.length() == 4) { + authMethod = "NTLM"; + break; + } + if (currentAuthMethod.indexOf(' ') != 4) continue; + authMethod = "NTLM"; + authorization = currentAuthMethod.substring(5).trim(); + break; + } else if (currentAuthMethod.startsWith("Negotiate")) { + if (currentAuthMethod.length() == 9) { + authMethod = "Negotiate"; + break; + } + if (currentAuthMethod.indexOf(' ') != 9) continue; + authMethod = "Negotiate"; + authorization = currentAuthMethod.substring(10).trim(); + break; + } + } + if (authMethod == null) return null; + NtlmMessage message = (authorization != null) ? + new Type2Message(Base64.decode(authorization)) : null; + reconnect(); + if (message == null) { + message = new Type1Message(); + if (LM_COMPATIBILITY > 2) { + message.setFlag(NtlmFlags.NTLMSSP_REQUEST_TARGET, true); + } + } else { + String domain = DEFAULT_DOMAIN; + String user = Type3Message.getDefaultUser(); + String password = Type3Message.getDefaultPassword(); + String userInfo = url.getUserInfo(); + if (userInfo != null) { + userInfo = URLDecoder.decode(userInfo); + int index = userInfo.indexOf(':'); + user = (index != -1) ? userInfo.substring(0, index) : userInfo; + if (index != -1) password = userInfo.substring(index + 1); + index = user.indexOf('\\'); + if (index == -1) index = user.indexOf('/'); + domain = (index != -1) ? user.substring(0, index) : domain; + user = (index != -1) ? user.substring(index + 1) : user; + } + if (user == null) { + if (!allowUserInteraction) return null; + try { + URL url = getURL(); + String protocol = url.getProtocol(); + int port = url.getPort(); + if (port == -1) { + port = "https".equalsIgnoreCase(protocol) ? 443 : 80; + } + PasswordAuthentication auth = + Authenticator.requestPasswordAuthentication(null, + port, protocol, "", authMethod); + if (auth == null) return null; + user = auth.getUserName(); + password = new String(auth.getPassword()); + } catch (Exception ex) { } + } + Type2Message type2 = (Type2Message) message; + message = new Type3Message(type2, password, domain, user, + Type3Message.getDefaultWorkstation(), 0); + } + return message; + } + + private void reconnect() throws IOException { + connection = (HttpURLConnection) connection.getURL().openConnection(); + connection.setRequestMethod(method); + headerFields = null; + Iterator properties = requestProperties.entrySet().iterator(); + while (properties.hasNext()) { + Map.Entry property = (Map.Entry) properties.next(); + String key = (String) property.getKey(); + StringBuffer value = new StringBuffer(); + Iterator values = ((List) property.getValue()).iterator(); + while (values.hasNext()) { + value.append(values.next()); + if (values.hasNext()) value.append(", "); + } + connection.setRequestProperty(key, value.toString()); + } + connection.setAllowUserInteraction(allowUserInteraction); + connection.setDoInput(doInput); + connection.setDoOutput(doOutput); + connection.setIfModifiedSince(ifModifiedSince); + connection.setUseCaches(useCaches); + } + + private static class CacheStream extends OutputStream { + + private final OutputStream stream; + + private final OutputStream collector; + + public CacheStream(OutputStream stream, OutputStream collector) { + this.stream = stream; + this.collector = collector; + } + + public void close() throws IOException { + stream.close(); + collector.close(); + } + + public void flush() throws IOException { + stream.flush(); + collector.flush(); + } + + public void write(byte[] b) throws IOException { + stream.write(b); + collector.write(b); + } + + public void write(byte[] b, int off, int len) throws IOException { + stream.write(b, off, len); + collector.write(b, off, len); + } + + public void write(int b) throws IOException { + stream.write(b); + collector.write(b); + } + + } + +} diff --git a/src/jcifs/http/NtlmServlet.java b/src/jcifs/http/NtlmServlet.java new file mode 100644 index 0000000..1679ea9 --- /dev/null +++ b/src/jcifs/http/NtlmServlet.java @@ -0,0 +1,169 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.http; + +import java.io.IOException; + +import java.net.UnknownHostException; + +import java.util.Enumeration; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.UnavailableException; + +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import jcifs.Config; +import jcifs.UniAddress; + +import jcifs.smb.NtlmPasswordAuthentication; +import jcifs.smb.SmbAuthException; +import jcifs.smb.SmbSession; + +import jcifs.util.Base64; + +import jcifs.netbios.NbtAddress; + +/** + * This servlet may be used with pre-2.3 servlet containers + * to protect content with NTLM HTTP Authentication. Servlets that + * extend this abstract base class may be authenticatied against an SMB + * server or domain controller depending on how the + * jcifs.smb.client.domain or jcifs.http.domainController + * properties are be specified. With later containers the + * NtlmHttpFilter should be used/b>. For custom NTLM HTTP Authentication schemes the NtlmSsp may be used. + *

+ * Read jCIFS NTLM HTTP Authentication and the Network Explorer Servlet related information. + */ + +public abstract class NtlmServlet extends HttpServlet { + + private String defaultDomain; + + private String domainController; + + private boolean loadBalance; + + private boolean enableBasic; + + private boolean insecureBasic; + + private String realm; + + public void init(ServletConfig config) throws ServletException { + super.init(config); + + /* Set jcifs properties we know we want; soTimeout and cachePolicy to 10min. + */ + Config.setProperty( "jcifs.smb.client.soTimeout", "300000" ); + Config.setProperty( "jcifs.netbios.cachePolicy", "600" ); + + Enumeration e = config.getInitParameterNames(); + String name; + while (e.hasMoreElements()) { + name = (String) e.nextElement(); + if (name.startsWith("jcifs.")) { + Config.setProperty(name, config.getInitParameter(name)); + } + } + defaultDomain = Config.getProperty("jcifs.smb.client.domain"); + domainController = Config.getProperty("jcifs.http.domainController"); + if( domainController == null ) { + domainController = defaultDomain; + loadBalance = Config.getBoolean( "jcifs.http.loadBalance", true ); + } + enableBasic = Boolean.valueOf( + Config.getProperty("jcifs.http.enableBasic")).booleanValue(); + insecureBasic = Boolean.valueOf( + Config.getProperty("jcifs.http.insecureBasic")).booleanValue(); + realm = Config.getProperty("jcifs.http.basicRealm"); + if (realm == null) realm = "jCIFS"; + } + + protected void service(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + UniAddress dc; + boolean offerBasic = enableBasic && + (insecureBasic || request.isSecure()); + String msg = request.getHeader("Authorization"); + if (msg != null && (msg.startsWith("NTLM ") || + (offerBasic && msg.startsWith("Basic ")))) { + if( loadBalance ) { + dc = new UniAddress( NbtAddress.getByName( domainController, 0x1C, null )); + } else { + dc = UniAddress.getByName( domainController, true ); + } + NtlmPasswordAuthentication ntlm; + if (msg.startsWith("NTLM ")) { + byte[] challenge = SmbSession.getChallenge(dc); + ntlm = NtlmSsp.authenticate(request, response, challenge); + if (ntlm == null) return; + } else { + String auth = new String(Base64.decode(msg.substring(6)), + "US-ASCII"); + int index = auth.indexOf(':'); + String user = (index != -1) ? auth.substring(0, index) : auth; + String password = (index != -1) ? auth.substring(index + 1) : + ""; + index = user.indexOf('\\'); + if (index == -1) index = user.indexOf('/'); + String domain = (index != -1) ? user.substring(0, index) : + defaultDomain; + user = (index != -1) ? user.substring(index + 1) : user; + ntlm = new NtlmPasswordAuthentication(domain, user, password); + } + try { + SmbSession.logon(dc, ntlm); + } catch (SmbAuthException sae) { + response.setHeader("WWW-Authenticate", "NTLM"); + if (offerBasic) { + response.addHeader("WWW-Authenticate", "Basic realm=\"" + + realm + "\""); + } + response.setHeader("Connection", "close"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.flushBuffer(); + return; + } + HttpSession ssn = request.getSession(); + ssn.setAttribute("NtlmHttpAuth", ntlm); + ssn.setAttribute( "ntlmdomain", ntlm.getDomain() ); + ssn.setAttribute( "ntlmuser", ntlm.getUsername() ); + } else { + HttpSession ssn = request.getSession(false); + if (ssn == null || ssn.getAttribute("NtlmHttpAuth") == null) { + response.setHeader("WWW-Authenticate", "NTLM"); + if (offerBasic) { + response.addHeader("WWW-Authenticate", "Basic realm=\"" + + realm + "\""); + } + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.flushBuffer(); + return; + } + } + super.service(request, response); + } +} + diff --git a/src/jcifs/http/NtlmSsp.java b/src/jcifs/http/NtlmSsp.java new file mode 100644 index 0000000..132d281 --- /dev/null +++ b/src/jcifs/http/NtlmSsp.java @@ -0,0 +1,111 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * "Jason Pugsley" + * "skeetz" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.http; + +import java.io.IOException; + +import javax.servlet.ServletException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import jcifs.smb.NtlmPasswordAuthentication; + +import jcifs.util.Base64; + +import jcifs.ntlmssp.NtlmFlags; +import jcifs.ntlmssp.Type1Message; +import jcifs.ntlmssp.Type2Message; +import jcifs.ntlmssp.Type3Message; + +/** + * This class is used internally by NtlmHttpFilter, + * NtlmServlet, and NetworkExplorer to negiotiate password + * hashes via NTLM SSP with MSIE. It might also be used directly by servlet + * containers to incorporate similar functionality. + *

+ * How NTLMSSP is used in conjunction with HTTP and MSIE clients is + * described in an NTLM + * Authentication Scheme for HTTP.

Also, read jCIFS NTLM HTTP Authentication and + * the Network Explorer Servlet related information. + */ + +public class NtlmSsp implements NtlmFlags { + + /** + * Calls the static {@link #authenticate(HttpServletRequest, + * HttpServletResponse, byte[])} method to perform NTLM authentication + * for the specified servlet request. + * + * @param req The request being serviced. + * @param resp The response. + * @param challenge The domain controller challenge. + * @throws IOException If an IO error occurs. + * @throws ServletException If an error occurs. + */ + public NtlmPasswordAuthentication doAuthentication( + HttpServletRequest req, HttpServletResponse resp, byte[] challenge) + throws IOException, ServletException { + return authenticate(req, resp, challenge); + } + + /** + * Performs NTLM authentication for the servlet request. + * + * @param req The request being serviced. + * @param resp The response. + * @param challenge The domain controller challenge. + * @throws IOException If an IO error occurs. + * @throws ServletException If an error occurs. + */ + public static NtlmPasswordAuthentication authenticate( + HttpServletRequest req, HttpServletResponse resp, byte[] challenge) + throws IOException, ServletException { + String msg = req.getHeader("Authorization"); + if (msg != null && msg.startsWith("NTLM ")) { + byte[] src = Base64.decode(msg.substring(5)); + if (src[8] == 1) { + Type1Message type1 = new Type1Message(src); + Type2Message type2 = new Type2Message(type1, challenge, null); + msg = Base64.encode(type2.toByteArray()); + resp.setHeader( "WWW-Authenticate", "NTLM " + msg ); + } else if (src[8] == 3) { + Type3Message type3 = new Type3Message(src); + byte[] lmResponse = type3.getLMResponse(); + if (lmResponse == null) lmResponse = new byte[0]; + byte[] ntResponse = type3.getNTResponse(); + if (ntResponse == null) ntResponse = new byte[0]; + return new NtlmPasswordAuthentication(type3.getDomain(), + type3.getUser(), challenge, lmResponse, ntResponse); + } + } else { + resp.setHeader("WWW-Authenticate", "NTLM"); + } + resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + resp.setContentLength(0); + resp.flushBuffer(); + return null; + } + +} + diff --git a/src/jcifs/http/ne.css b/src/jcifs/http/ne.css new file mode 100644 index 0000000..21929f0 --- /dev/null +++ b/src/jcifs/http/ne.css @@ -0,0 +1,68 @@ + a { + display: block; + float: left; + width: 300px; + height: 50px; + padding: 2px; + font-family: Verdana, sans-serif; + font-size: 10pt; + color: #000000; + text-decoration: none; + } + a.plain { + display: inline; + float: none; + width: auto; + height: auto; + } + a.sort { + display: block; + float: left; + width: 100px; + height: 15px; + font-family: Verdana, sans-serif; + font-size: 8pt; + font-weight: bold; + text-decoration: none; + color: #000000; + background-color: #d0d0d0; + border-top-color: #ffffff; + border-bottom-color: #707070; + border-right-color: #707070; + border-left-color: #ffffff; + border-style: solid solid; + border-top-width: 1px; + border-bottom-width: 2px; + border-right-width: 2px; + border-left-width: 1px; + } + a:visited { + color: #333897; + } + a.sort:hover { + background-color: #d0d0d0; + } + a.sort:visited { + color: #000000; + } + div { + float: left; + width: 100px; + height: 18px; + padding: 2px; + font-family: Verdana, sans-serif; + font-size: 10pt; + } + body { + font-family: Verdana, sans-serif; + font-size: 10pt; + background-color: #ffffff; + margin-top: 0; + margin-left: 5; + } + small { + font-size: 8pt; + } + big { + font-size: 14pt; + } diff --git a/src/jcifs/https/Handler.java b/src/jcifs/https/Handler.java new file mode 100644 index 0000000..bef957c --- /dev/null +++ b/src/jcifs/https/Handler.java @@ -0,0 +1,44 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.https; + +/** + * A URLStreamHandler used to provide NTLM authentication + * capabilities to the default HTTPS handler. This acts as a wrapper, + * handling authentication and passing control to the underlying + * stream handler. + */ +public class Handler extends jcifs.http.Handler { + + /** + * The default HTTPS port (443). + */ + public static final int DEFAULT_HTTPS_PORT = 443; + + /** + * Returns the default HTTPS port. + * + * @return An int containing the default HTTPS port. + */ + protected int getDefaultPort() { + return DEFAULT_HTTPS_PORT; + } + +} diff --git a/src/jcifs/netbios/Lmhosts.java b/src/jcifs/netbios/Lmhosts.java new file mode 100644 index 0000000..2ea74c5 --- /dev/null +++ b/src/jcifs/netbios/Lmhosts.java @@ -0,0 +1,156 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.BufferedReader; +import java.io.IOException; +import java.util.Hashtable; +import java.net.UnknownHostException; +import jcifs.Config; +import jcifs.smb.SmbFileInputStream; +import jcifs.util.LogStream; + +public class Lmhosts { + + private static final String FILENAME = Config.getProperty( "jcifs.netbios.lmhosts" ); + private static final Hashtable TAB = new Hashtable(); + private static long lastModified = 1L; + private static int alt; + private static LogStream log = LogStream.getInstance(); + + /** + * This is really just for {@link jcifs.UniAddress}. It does + * not throw an {@link java.net.UnknownHostException} because this + * is queried frequently and exceptions would be rather costly to + * throw on a regular basis here. + */ + + public synchronized static NbtAddress getByName( String host ) { + return getByName( new Name( host, 0x20, null )); + } + + synchronized static NbtAddress getByName( Name name ) { + NbtAddress result = null; + + try { + if( FILENAME != null ) { + File f = new File( FILENAME ); + long lm; + + if(( lm = f.lastModified() ) > lastModified ) { + lastModified = lm; + TAB.clear(); + alt = 0; + populate( new FileReader( f )); + } + result = (NbtAddress)TAB.get( name ); + } + } catch( FileNotFoundException fnfe ) { + if( log.level > 1 ) { + log.println( "lmhosts file: " + FILENAME ); + fnfe.printStackTrace( log ); + } + } catch( IOException ioe ) { + if( log.level > 0 ) + ioe.printStackTrace( log ); + } + return result; + } + + static void populate( Reader r ) throws IOException { + String line; + BufferedReader br = new BufferedReader( r ); + + while(( line = br.readLine() ) != null ) { + line = line.toUpperCase().trim(); + if( line.length() == 0 ) { + continue; + } else if( line.charAt( 0 ) == '#' ) { + if( line.startsWith( "#INCLUDE " )) { + line = line.substring( line.indexOf( '\\' )); + String url = "smb:" + line.replace( '\\', '/' ); + + if( alt > 0 ) { + try { + populate( new InputStreamReader( new SmbFileInputStream( url ))); + } catch( IOException ioe ) { + log.println( "lmhosts URL: " + url ); + ioe.printStackTrace( log ); + continue; + } + + /* An include was loaded successfully. We can skip + * all other includes up to the #END_ALTERNATE tag. + */ + + alt--; + while(( line = br.readLine() ) != null ) { + line = line.toUpperCase().trim(); + if( line.startsWith( "#END_ALTERNATE" )) { + break; + } + } + } else { + populate( new InputStreamReader( new SmbFileInputStream( url ))); + } + } else if( line.startsWith( "#BEGIN_ALTERNATE" )) { + alt++; + } else if( line.startsWith( "#END_ALTERNATE" ) && alt > 0 ) { + alt--; + throw new IOException( "no lmhosts alternate includes loaded" ); + } + } else if( Character.isDigit( line.charAt( 0 ))) { + char[] data = line.toCharArray(); + int ip, i, j; + Name name; + NbtAddress addr; + char c; + + c = '.'; + ip = i = 0; + for( ; i < data.length && c == '.'; i++ ) { + int b = 0x00; + + for( ; i < data.length && ( c = data[i] ) >= 48 && c <= 57; i++ ) { + b = b * 10 + c - '0'; + } + ip = ( ip << 8 ) + b; + } + while( i < data.length && Character.isWhitespace( data[i] )) { + i++; + } + j = i; + while( j < data.length && Character.isWhitespace( data[j] ) == false ) { + j++; + } + + name = new Name( line.substring( i, j ), 0x20, null ); + addr = new NbtAddress( name, ip, false, NbtAddress.B_NODE, + false, false, true, true, + NbtAddress.UNKNOWN_MAC_ADDRESS ); + TAB.put( name, addr ); + } + } + } +} diff --git a/src/jcifs/netbios/Name.java b/src/jcifs/netbios/Name.java new file mode 100644 index 0000000..a205929 --- /dev/null +++ b/src/jcifs/netbios/Name.java @@ -0,0 +1,199 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * "Christopher R. Hertel" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.io.UnsupportedEncodingException; +import jcifs.Config; +import jcifs.util.Hexdump; + +public class Name { + + private static final int TYPE_OFFSET = 31; + private static final int SCOPE_OFFSET = 33; + private static final String DEFAULT_SCOPE = Config.getProperty( "jcifs.netbios.scope" ); + + static final String OEM_ENCODING = + Config.getProperty( "jcifs.encoding", + System.getProperty( "file.encoding" )); + + public String name, scope; + public int hexCode; + int srcHashCode; /* srcHashCode must be set by name resolution + * routines before entry into addressCache + */ + + Name() { + } + public Name( String name, int hexCode, String scope ) { + if( name.length() > 15 ) { + name = name.substring( 0, 15 ); + } + this.name = name.toUpperCase(); + this.hexCode = hexCode; + this.scope = scope != null && scope.length() > 0 ? scope : DEFAULT_SCOPE; + this.srcHashCode = 0; + } + + int writeWireFormat( byte[] dst, int dstIndex ) { + // write 0x20 in first byte + dst[dstIndex] = 0x20; + + // write name + try { + byte tmp[] = name.getBytes( Name.OEM_ENCODING ); + int i; + for( i = 0; i < tmp.length; i++ ) { + dst[dstIndex + ( 2 * i + 1 )] = (byte)((( tmp[i] & 0xF0 ) >> 4 ) + 0x41 ); + dst[dstIndex + ( 2 * i + 2 )] = (byte)(( tmp[i] & 0x0F ) + 0x41 ); + } + for( ; i < 15; i++ ) { + dst[dstIndex + ( 2 * i + 1 )] = (byte)0x43; + dst[dstIndex + ( 2 * i + 2 )] = (byte)0x41; + } + dst[dstIndex + TYPE_OFFSET] = (byte)((( hexCode & 0xF0 ) >> 4 ) + 0x41 ); + dst[dstIndex + TYPE_OFFSET + 1] = (byte)(( hexCode & 0x0F ) + 0x41 ); + } catch( UnsupportedEncodingException uee ) { + } + return SCOPE_OFFSET + writeScopeWireFormat( dst, dstIndex + SCOPE_OFFSET ); + } + + int readWireFormat( byte[] src, int srcIndex ) { + + byte tmp[] = new byte[SCOPE_OFFSET]; + int length = 15; + for( int i = 0; i < 15; i++ ) { + tmp[i] = (byte)((( src[srcIndex + ( 2 * i + 1 )] & 0xFF ) - 0x41 ) << 4 ); + tmp[i] |= (byte)((( src[srcIndex + ( 2 * i + 2 )] & 0xFF ) - 0x41 ) & 0x0F ); + if( tmp[i] != (byte)' ' ) { + length = i + 1; + } + } + try { + name = new String( tmp, 0, length, Name.OEM_ENCODING ); + } catch( UnsupportedEncodingException uee ) { + } + hexCode = (( src[srcIndex + TYPE_OFFSET] & 0xFF ) - 0x41 ) << 4; + hexCode |= (( src[srcIndex + TYPE_OFFSET + 1] & 0xFF ) - 0x41 ) & 0x0F; + return SCOPE_OFFSET + readScopeWireFormat( src, srcIndex + SCOPE_OFFSET ); + } + int writeScopeWireFormat( byte[] dst, int dstIndex ) { + if( scope == null ) { + dst[dstIndex] = (byte)0x00; + return 1; + } + + // copy new scope in + dst[dstIndex++] = (byte)'.'; + try { + System.arraycopy( scope.getBytes( Name.OEM_ENCODING ), 0, dst, dstIndex, scope.length() ); + } catch( UnsupportedEncodingException uee ) { + } + dstIndex += scope.length(); + + dst[dstIndex++] = (byte)0x00; + + // now go over scope backwards converting '.' to label length + + int i = dstIndex - 2; + int e = i - scope.length(); + int c = 0; + + do { + if( dst[i] == '.' ) { + dst[i] = (byte)c; + c = 0; + } else { + c++; + } + } while( i-- > e ); + return scope.length() + 2; + } + int readScopeWireFormat( byte[] src, int srcIndex ) { + int start = srcIndex; + int n; + StringBuffer sb; + + if(( n = src[srcIndex++] & 0xFF ) == 0 ) { + scope = null; + return 1; + } + + try { + sb = new StringBuffer( new String( src, srcIndex, n, Name.OEM_ENCODING )); + srcIndex += n; + while(( n = src[srcIndex++] & 0xFF ) != 0 ) { + sb.append( '.' ).append( new String( src, srcIndex, n, Name.OEM_ENCODING )); + srcIndex += n; + } + scope = sb.toString(); + } catch( UnsupportedEncodingException uee ) { + } + + return srcIndex - start; + } + + public int hashCode() { + int result; + + result = name.hashCode(); + result += 65599 * hexCode; + result += 65599 * srcHashCode; /* hashCode is different depending + * on where it came from + */ + if( scope != null && scope.length() != 0 ) { + result += scope.hashCode(); + } + return result; + } + public boolean equals( Object obj ) { + Name n; + + if( !( obj instanceof Name )) { + return false; + } + n = (Name)obj; + if( scope == null && n.scope == null ) { + return name.equals( n.name ) && hexCode == n.hexCode; + } + return name.equals( n.name ) && hexCode == n.hexCode && scope.equals( n.scope ); + } + public String toString() { + StringBuffer sb = new StringBuffer(); + String n = name; + + // fix MSBROWSE name + if( n == null ) { + n = "null"; + } else if( n.charAt( 0 ) == 0x01 ) { + char c[] = n.toCharArray(); + c[0] = '.'; + c[1] = '.'; + c[14] = '.'; + n = new String( c ); + } + + sb.append( n ).append( "<" ).append( Hexdump.toHexString( hexCode, 2 )).append( ">" ); + if( scope != null ) { + sb.append( "." ).append( scope ); + } + return sb.toString(); + } +} + diff --git a/src/jcifs/netbios/NameQueryRequest.java b/src/jcifs/netbios/NameQueryRequest.java new file mode 100644 index 0000000..e0c58f5 --- /dev/null +++ b/src/jcifs/netbios/NameQueryRequest.java @@ -0,0 +1,44 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +class NameQueryRequest extends NameServicePacket { + + NameQueryRequest( Name name ) { + questionName = name; + questionType = NB; + } + + int writeBodyWireFormat( byte[] dst, int dstIndex ) { + return writeQuestionSectionWireFormat( dst, dstIndex ); + } + int readBodyWireFormat( byte[] src, int srcIndex ) { + return readQuestionSectionWireFormat( src, srcIndex ); + } + int writeRDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readRDataWireFormat( byte[] src, int srcIndex ) { + return 0; + } + public String toString() { + return new String( "NameQueryRequest[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/netbios/NameQueryResponse.java b/src/jcifs/netbios/NameQueryResponse.java new file mode 100644 index 0000000..0f94534 --- /dev/null +++ b/src/jcifs/netbios/NameQueryResponse.java @@ -0,0 +1,57 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +class NameQueryResponse extends NameServicePacket { + + NameQueryResponse() { + recordName = new Name(); + } + + int writeBodyWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readBodyWireFormat( byte[] src, int srcIndex ) { + return readResourceRecordWireFormat( src, srcIndex ); + } + int writeRDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readRDataWireFormat( byte[] src, int srcIndex ) { + if( resultCode != 0 || opCode != QUERY ) { + return 0; + } + boolean groupName = (( src[srcIndex] & 0x80 ) == 0x80 ) ? true : false; + int nodeType = ( src[srcIndex] & 0x60 ) >> 5; + srcIndex += 2; + int address = readInt4( src, srcIndex ); + if( address != 0 ) { + addrEntry[addrIndex] = new NbtAddress( recordName, address, groupName, nodeType ); + } else { + addrEntry[addrIndex] = null; + } + + return 6; + } + public String toString() { + return new String( "NameQueryResponse[" + + super.toString() + + ",addrEntry=" + addrEntry + "]" ); + } +} diff --git a/src/jcifs/netbios/NameServiceClient.java b/src/jcifs/netbios/NameServiceClient.java new file mode 100644 index 0000000..2927892 --- /dev/null +++ b/src/jcifs/netbios/NameServiceClient.java @@ -0,0 +1,443 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.net.*; +import java.io.IOException; +import java.util.HashMap; +import java.util.StringTokenizer; +import jcifs.Config; +import jcifs.util.Hexdump; +import jcifs.util.LogStream; + +class NameServiceClient implements Runnable { + + static final int DEFAULT_SO_TIMEOUT = 5000; + static final int DEFAULT_RCV_BUF_SIZE = 576; + static final int DEFAULT_SND_BUF_SIZE = 576; + static final int NAME_SERVICE_UDP_PORT = 137; + static final int DEFAULT_RETRY_COUNT = 2; + static final int DEFAULT_RETRY_TIMEOUT = 3000; + + static final int RESOLVER_LMHOSTS = 1; + static final int RESOLVER_BCAST = 2; + static final int RESOLVER_WINS = 3; + + private static final int SND_BUF_SIZE = Config.getInt( "jcifs.netbios.snd_buf_size", DEFAULT_SND_BUF_SIZE ); + private static final int RCV_BUF_SIZE = Config.getInt( "jcifs.netbios.rcv_buf_size", DEFAULT_RCV_BUF_SIZE ); + private static final int SO_TIMEOUT = Config.getInt( "jcifs.netbios.soTimeout", DEFAULT_SO_TIMEOUT ); + private static final int RETRY_COUNT = Config.getInt( "jcifs.netbios.retryCount", DEFAULT_RETRY_COUNT ); + private static final int RETRY_TIMEOUT = Config.getInt( "jcifs.netbios.retryTimeout", DEFAULT_RETRY_TIMEOUT); + private static final int LPORT = Config.getInt( "jcifs.netbios.lport", 0 ); + private static final InetAddress LADDR = Config.getInetAddress( "jcifs.netbios.laddr", null ); + private static final String RO = Config.getProperty( "jcifs.resolveOrder" ); + + private static LogStream log = LogStream.getInstance(); + + private final Object LOCK = new Object(); + + private int lport, closeTimeout; + private byte[] snd_buf, rcv_buf; + private DatagramSocket socket; + private DatagramPacket in, out; + private HashMap responseTable = new HashMap(); + private Thread thread; + private int nextNameTrnId = 0; + private int[] resolveOrder; + + InetAddress laddr, baddr; + + NameServiceClient() { + this( LPORT, LADDR ); + } + NameServiceClient( int lport, InetAddress laddr ) { + this.lport = lport; + this.laddr = laddr; + + try { + baddr = Config.getInetAddress( "jcifs.netbios.baddr", + InetAddress.getByName( "255.255.255.255" )); + } catch( UnknownHostException uhe ) { + } + + snd_buf = new byte[SND_BUF_SIZE]; + rcv_buf = new byte[RCV_BUF_SIZE]; + out = new DatagramPacket( snd_buf, SND_BUF_SIZE, baddr, NAME_SERVICE_UDP_PORT ); + in = new DatagramPacket( rcv_buf, RCV_BUF_SIZE ); + + if( RO == null || RO.length() == 0 ) { + + /* No resolveOrder has been specified, use the + * default which is LMHOSTS,DNS,WINS,BCAST + * LMHOSTS,BCAST,DNS if jcifs.netbios.wins has not + * been specified. + */ + + if( NbtAddress.getWINSAddress() == null ) { + resolveOrder = new int[2]; + resolveOrder[0] = RESOLVER_LMHOSTS; + resolveOrder[1] = RESOLVER_BCAST; + } else { + resolveOrder = new int[3]; + resolveOrder[0] = RESOLVER_LMHOSTS; + resolveOrder[1] = RESOLVER_WINS; + resolveOrder[2] = RESOLVER_BCAST; + } + } else { + int[] tmp = new int[3]; + StringTokenizer st = new StringTokenizer( RO, "," ); + int i = 0; + while( st.hasMoreTokens() ) { + String s = st.nextToken().trim(); + if( s.equalsIgnoreCase( "LMHOSTS" )) { + tmp[i++] = RESOLVER_LMHOSTS; + } else if( s.equalsIgnoreCase( "WINS" )) { + if( NbtAddress.getWINSAddress() == null ) { + if( log.level > 1 ) { + log.println( "NetBIOS resolveOrder specifies WINS however the " + + "jcifs.netbios.wins property has not been set" ); + } + continue; + } + tmp[i++] = RESOLVER_WINS; + } else if( s.equalsIgnoreCase( "BCAST" )) { + tmp[i++] = RESOLVER_BCAST; + } else if( s.equalsIgnoreCase( "DNS" )) { + ; // skip + } else if( log.level > 1 ) { + log.println( "unknown resolver method: " + s ); + } + } + resolveOrder = new int[i]; + System.arraycopy( tmp, 0, resolveOrder, 0, i ); + } + } + + int getNextNameTrnId() { + if(( ++nextNameTrnId & 0xFFFF ) == 0 ) { + nextNameTrnId = 1; + } + return nextNameTrnId; + } + void ensureOpen( int timeout ) throws IOException { + closeTimeout = 0; + if( SO_TIMEOUT != 0 ) { + closeTimeout = Math.max( SO_TIMEOUT, timeout ); + } + // If socket is still good, the new closeTimeout will + // be ignored; see tryClose comment. + if( socket == null ) { + socket = new DatagramSocket( lport, laddr ); + thread = new Thread( this, "JCIFS-NameServiceClient" ); + thread.setDaemon( true ); + thread.start(); + } + } + void tryClose() { + synchronized( LOCK ) { + + /* Yes, there is the potential to drop packets + * because we might close the socket during a + * request. However the chances are slim and the + * retry code should ensure the overall request + * is serviced. The alternative complicates things + * more than I think is worth it. + */ + + if( socket != null ) { + socket.close(); + socket = null; + } + thread = null; + responseTable.clear(); + } + } + public void run() { + int nameTrnId; + NameServicePacket response; + + try { + while( thread == Thread.currentThread() ) { + in.setLength( RCV_BUF_SIZE ); + + socket.setSoTimeout( closeTimeout ); + socket.receive( in ); + + if( log.level > 3 ) + log.println( "NetBIOS: new data read from socket" ); + + nameTrnId = NameServicePacket.readNameTrnId( rcv_buf, 0 ); + response = (NameServicePacket)responseTable.get( new Integer( nameTrnId )); + if( response == null || response.received ) { + continue; + } + synchronized( response ) { + response.readWireFormat( rcv_buf, 0 ); + response.received = true; + + if( log.level > 3 ) { + log.println( response ); + Hexdump.hexdump( log, rcv_buf, 0, in.getLength() ); + } + + response.notify(); + } + } + } catch(SocketTimeoutException ste) { + } catch( Exception ex ) { + if( log.level > 2 ) + ex.printStackTrace( log ); + } finally { + tryClose(); + } + } + void send( NameServicePacket request, NameServicePacket response, + int timeout ) throws IOException { + Integer nid = null; + int max = NbtAddress.NBNS.length; + + if (max == 0) + max = 1; /* No WINs, try only bcast addr */ + + synchronized( response ) { + while (max-- > 0) { + try { + synchronized( LOCK ) { + request.nameTrnId = getNextNameTrnId(); + nid = new Integer( request.nameTrnId ); + + out.setAddress( request.addr ); + out.setLength( request.writeWireFormat( snd_buf, 0 )); + response.received = false; + + responseTable.put( nid, response ); + ensureOpen( timeout + 1000 ); + socket.send( out ); + + if( log.level > 3 ) { + log.println( request ); + Hexdump.hexdump( log, snd_buf, 0, out.getLength() ); + } + } + + long start = System.currentTimeMillis(); + while (timeout > 0) { + response.wait( timeout ); + + /* JetDirect printer can respond to regular broadcast query + * with node status so we need to check to make sure that + * the record type matches the question type and if not, + * loop around and try again. + */ + if (response.received && request.questionType == response.recordType) + return; + + response.received = false; + timeout -= System.currentTimeMillis() - start; + } + + } catch( InterruptedException ie ) { + throw new IOException(ie.getMessage()); + } finally { + responseTable.remove( nid ); + } + + synchronized (LOCK) { + if (NbtAddress.isWINS( request.addr ) == false) + break; + /* Message was sent to WINS but + * failed to receive response. + * Try a different WINS server. + */ + if (request.addr == NbtAddress.getWINSAddress()) + NbtAddress.switchWINS(); + request.addr = NbtAddress.getWINSAddress(); + } + } + } + } + + NbtAddress[] getAllByName( Name name, InetAddress addr ) + throws UnknownHostException { + int n; + NameQueryRequest request = new NameQueryRequest( name ); + NameQueryResponse response = new NameQueryResponse(); + + request.addr = addr != null ? addr : NbtAddress.getWINSAddress(); + request.isBroadcast = request.addr == null; + + if( request.isBroadcast ) { + request.addr = baddr; + n = RETRY_COUNT; + } else { + request.isBroadcast = false; + n = 1; + } + + do { + try { + send( request, response, RETRY_TIMEOUT ); + } catch( IOException ioe ) { + if( log.level > 1 ) + ioe.printStackTrace( log ); + throw new UnknownHostException( name.name ); + } + + if( response.received && response.resultCode == 0 ) { + return response.addrEntry; + } + } while( --n > 0 && request.isBroadcast ); + + throw new UnknownHostException( name.name ); + } + NbtAddress getByName( Name name, InetAddress addr ) + throws UnknownHostException { + int n; + NameQueryRequest request = new NameQueryRequest( name ); + NameQueryResponse response = new NameQueryResponse(); + + if( addr != null ) { /* UniAddress calls always use this + * because it specifies addr + */ + request.addr = addr; /* if addr ends with 255 flag it bcast */ + request.isBroadcast = (addr.getAddress()[3] == (byte)0xFF); + + n = RETRY_COUNT; + do { + try { + send( request, response, RETRY_TIMEOUT ); + } catch( IOException ioe ) { + if( log.level > 1 ) + ioe.printStackTrace( log ); + throw new UnknownHostException( name.name ); + } + + if( response.received && response.resultCode == 0 ) { + int last = response.addrEntry.length - 1; + response.addrEntry[last].hostName.srcHashCode = addr.hashCode(); + return response.addrEntry[last]; + } + } while( --n > 0 && request.isBroadcast ); + + throw new UnknownHostException( name.name ); + } + + /* If a target address to query was not specified explicitly + * with the addr parameter we fall into this resolveOrder routine. + */ + + for( int i = 0; i < resolveOrder.length; i++ ) { + try { + switch( resolveOrder[i] ) { + case RESOLVER_LMHOSTS: + NbtAddress ans = Lmhosts.getByName( name ); + if( ans != null ) { + ans.hostName.srcHashCode = 0; // just has to be different + // from other methods + return ans; + } + break; + case RESOLVER_WINS: + case RESOLVER_BCAST: + if( resolveOrder[i] == RESOLVER_WINS && + name.name != NbtAddress.MASTER_BROWSER_NAME && + name.hexCode != 0x1d ) { + request.addr = NbtAddress.getWINSAddress(); + request.isBroadcast = false; + } else { + request.addr = baddr; + request.isBroadcast = true; + } + + n = RETRY_COUNT; + while( n-- > 0 ) { + try { + send( request, response, RETRY_TIMEOUT ); + } catch( IOException ioe ) { + if( log.level > 1 ) + ioe.printStackTrace( log ); + throw new UnknownHostException( name.name ); + } + if( response.received && response.resultCode == 0 ) { + +/* Before we return, in anticipation of this address being cached we must + * augment the addresses name's hashCode to distinguish those resolved by + * Lmhosts, WINS, or BCAST. Otherwise a failed query from say WINS would + * get pulled out of the cache for a BCAST on the same name. + */ + response.addrEntry[0].hostName.srcHashCode = + request.addr.hashCode(); + return response.addrEntry[0]; + } else if( resolveOrder[i] == RESOLVER_WINS ) { + /* If WINS reports negative, no point in retry + */ + break; + } + } + break; + } + } catch( IOException ioe ) { + } + } + throw new UnknownHostException( name.name ); + } + NbtAddress[] getNodeStatus( NbtAddress addr ) throws UnknownHostException { + int n, srcHashCode; + NodeStatusRequest request; + NodeStatusResponse response; + + response = new NodeStatusResponse( addr ); + request = new NodeStatusRequest( + new Name( NbtAddress.ANY_HOSTS_NAME, 0x00, null)); + request.addr = addr.getInetAddress(); + + n = RETRY_COUNT; + while( n-- > 0 ) { + try { + send( request, response, RETRY_TIMEOUT ); + } catch( IOException ioe ) { + if( log.level > 1 ) + ioe.printStackTrace( log ); + throw new UnknownHostException( addr.toString() ); + } + if( response.received && response.resultCode == 0 ) { + + /* For name queries resolved by different sources (e.g. WINS, + * BCAST, Node Status) we need to augment the hashcode generated + * for the addresses hostname or failed lookups for one type will + * be cached and cause other types to fail even though they may + * not be the authority for the name. For example, if a WINS lookup + * for FOO fails and caches unknownAddress for FOO, a subsequent + * lookup for FOO using BCAST should not fail because of that + * name cached from WINS. + * + * So, here we apply the source addresses hashCode to each name to + * make them specific to who resolved the name. + */ + + srcHashCode = request.addr.hashCode(); + for( int i = 0; i < response.addressArray.length; i++ ) { + response.addressArray[i].hostName.srcHashCode = srcHashCode; + } + return response.addressArray; + } + } + throw new UnknownHostException( addr.hostName.name ); + } +} diff --git a/src/jcifs/netbios/NameServicePacket.java b/src/jcifs/netbios/NameServicePacket.java new file mode 100644 index 0000000..303fac2 --- /dev/null +++ b/src/jcifs/netbios/NameServicePacket.java @@ -0,0 +1,337 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.net.InetAddress; +import jcifs.util.Hexdump; + +abstract class NameServicePacket { + + // opcode + static final int QUERY = 0; + static final int WACK = 7; + + // rcode + static final int FMT_ERR = 0x1; + static final int SRV_ERR = 0x2; + static final int IMP_ERR = 0x4; + static final int RFS_ERR = 0x5; + static final int ACT_ERR = 0x6; + static final int CFT_ERR = 0x7; + + // type/class + static final int NB_IN = 0x00200001; + static final int NBSTAT_IN = 0x00210001; + static final int NB = 0x0020; + static final int NBSTAT = 0x0021; + static final int IN = 0x0001; + static final int A = 0x0001; + static final int NS = 0x0002; + static final int NULL = 0x000a; + + static final int HEADER_LENGTH = 12; + + // header field offsets + static final int OPCODE_OFFSET = 2; + static final int QUESTION_OFFSET = 4; + static final int ANSWER_OFFSET = 6; + static final int AUTHORITY_OFFSET = 8; + static final int ADDITIONAL_OFFSET = 10; + + static void writeInt2( int val, byte[] dst, int dstIndex ) { + dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF ); + dst[dstIndex] = (byte)( val & 0xFF ); + } + static void writeInt4( int val, byte[] dst, int dstIndex ) { + dst[dstIndex++] = (byte)(( val >> 24 ) & 0xFF ); + dst[dstIndex++] = (byte)(( val >> 16 ) & 0xFF ); + dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF ); + dst[dstIndex] = (byte)( val & 0xFF ); + } + static int readInt2( byte[] src, int srcIndex ) { + return (( src[srcIndex] & 0xFF ) << 8 ) + + ( src[srcIndex + 1] & 0xFF ); + } + static int readInt4( byte[] src, int srcIndex ) { + return (( src[srcIndex] & 0xFF ) << 24 ) + + (( src[srcIndex + 1] & 0xFF ) << 16 ) + + (( src[srcIndex + 2] & 0xFF ) << 8 ) + + ( src[srcIndex + 3] & 0xFF ); + } + + static int readNameTrnId( byte[] src, int srcIndex ) { + return readInt2( src, srcIndex ); + } + + int addrIndex; + NbtAddress[] addrEntry; + + int nameTrnId; + + int opCode, + resultCode, + questionCount, + answerCount, + authorityCount, + additionalCount; + boolean received, + isResponse, + isAuthAnswer, + isTruncated, + isRecurDesired, + isRecurAvailable, + isBroadcast; + + Name questionName; + Name recordName; + + int questionType, + questionClass, + recordType, + recordClass, + ttl, + rDataLength; + + InetAddress addr; + + NameServicePacket() { + isRecurDesired = true; + isBroadcast = true; + questionCount = 1; + questionClass = IN; + } + + int writeWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + dstIndex += writeHeaderWireFormat( dst, dstIndex ); + dstIndex += writeBodyWireFormat( dst, dstIndex ); + return dstIndex - start; + } + int readWireFormat( byte[] src, int srcIndex ) { + int start = srcIndex; + srcIndex += readHeaderWireFormat( src, srcIndex ); + srcIndex += readBodyWireFormat( src, srcIndex ); + return srcIndex - start; + } + + int writeHeaderWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + writeInt2( nameTrnId, dst, dstIndex ); + dst[dstIndex + OPCODE_OFFSET] = (byte)(( isResponse ? 0x80 : 0x00 ) + + (( opCode << 3 ) & 0x78 ) + + ( isAuthAnswer ? 0x04 : 0x00 ) + + ( isTruncated ? 0x02 : 0x00 ) + + ( isRecurDesired ? 0x01 : 0x00 )); + dst[dstIndex + OPCODE_OFFSET + 1] = (byte)(( isRecurAvailable ? 0x80 : 0x00 ) + + ( isBroadcast ? 0x10 : 0x00 ) + + ( resultCode & 0x0F )); + writeInt2( questionCount, dst, start + QUESTION_OFFSET ); + writeInt2( answerCount, dst, start + ANSWER_OFFSET ); + writeInt2( authorityCount, dst, start + AUTHORITY_OFFSET ); + writeInt2( additionalCount, dst, start + ADDITIONAL_OFFSET ); + return HEADER_LENGTH; + } + int readHeaderWireFormat( byte[] src, int srcIndex ) { + nameTrnId = readInt2( src, srcIndex ); + isResponse = (( src[srcIndex + OPCODE_OFFSET] & 0x80 ) == 0 ) ? false : true; + opCode = ( src[srcIndex + OPCODE_OFFSET] & 0x78 ) >> 3; + isAuthAnswer = (( src[srcIndex + OPCODE_OFFSET] & 0x04 ) == 0 ) ? false : true; + isTruncated = (( src[srcIndex + OPCODE_OFFSET] & 0x02 ) == 0 ) ? false : true; + isRecurDesired = (( src[srcIndex + OPCODE_OFFSET] & 0x01 ) == 0 ) ? false : true; + isRecurAvailable = + (( src[srcIndex + OPCODE_OFFSET + 1] & 0x80 ) == 0 ) ? false : true; + isBroadcast = (( src[srcIndex + OPCODE_OFFSET + 1] & 0x10 ) == 0 ) ? false : true; + resultCode = src[srcIndex + OPCODE_OFFSET + 1] & 0x0F; + questionCount = readInt2( src, srcIndex + QUESTION_OFFSET ); + answerCount = readInt2( src, srcIndex + ANSWER_OFFSET ); + authorityCount = readInt2( src, srcIndex + AUTHORITY_OFFSET ); + additionalCount = readInt2( src, srcIndex + ADDITIONAL_OFFSET ); + return HEADER_LENGTH; + } + int writeQuestionSectionWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + dstIndex += questionName.writeWireFormat( dst, dstIndex ); + writeInt2( questionType, dst, dstIndex ); + dstIndex += 2; + writeInt2( questionClass, dst, dstIndex ); + dstIndex += 2; + return dstIndex - start; + } + int readQuestionSectionWireFormat( byte[] src, int srcIndex ) { + int start = srcIndex; + srcIndex += questionName.readWireFormat( src, srcIndex ); + questionType = readInt2( src, srcIndex ); + srcIndex += 2; + questionClass = readInt2( src, srcIndex ); + srcIndex += 2; + return srcIndex - start; + } + int writeResourceRecordWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + if( recordName == questionName ) { + dst[dstIndex++] = (byte)0xC0; // label string pointer to + dst[dstIndex++] = (byte)0x0C; // questionName (offset 12) + } else { + dstIndex += recordName.writeWireFormat( dst, dstIndex ); + } + writeInt2( recordType, dst, dstIndex ); + dstIndex += 2; + writeInt2( recordClass, dst, dstIndex ); + dstIndex += 2; + writeInt4( ttl, dst, dstIndex ); + dstIndex += 4; + rDataLength = writeRDataWireFormat( dst, dstIndex + 2 ); + writeInt2( rDataLength, dst, dstIndex ); + dstIndex += 2 + rDataLength; + return dstIndex - start; + } + int readResourceRecordWireFormat( byte[] src, int srcIndex ) { + int start = srcIndex; + int end; + + if(( src[srcIndex] & 0xC0 ) == 0xC0 ) { + recordName = questionName; // label string pointer to questionName + srcIndex += 2; + } else { + srcIndex += recordName.readWireFormat( src, srcIndex ); + } + recordType = readInt2( src, srcIndex ); + srcIndex += 2; + recordClass = readInt2( src, srcIndex ); + srcIndex += 2; + ttl = readInt4( src, srcIndex ); + srcIndex += 4; + rDataLength = readInt2( src, srcIndex ); + srcIndex += 2; + + addrEntry = new NbtAddress[rDataLength / 6]; + end = srcIndex + rDataLength; + for( addrIndex = 0; srcIndex < end; addrIndex++ ) { + srcIndex += readRDataWireFormat( src, srcIndex ); + } + + return srcIndex - start; + } + + abstract int writeBodyWireFormat( byte[] dst, int dstIndex ); + abstract int readBodyWireFormat( byte[] src, int srcIndex ); + abstract int writeRDataWireFormat( byte[] dst, int dstIndex ); + abstract int readRDataWireFormat( byte[] src, int srcIndex ); + + public String toString() { + String opCodeString, + resultCodeString, + questionTypeString, + questionClassString, + recordTypeString, + recordClassString; + + switch( opCode ) { + case QUERY: + opCodeString = "QUERY"; + break; + case WACK: + opCodeString = "WACK"; + break; + default: + opCodeString = Integer.toString( opCode ); + break; + } + switch( resultCode ) { + case FMT_ERR: + resultCodeString = "FMT_ERR"; + break; + case SRV_ERR: + resultCodeString = "SRV_ERR"; + break; + case IMP_ERR: + resultCodeString = "IMP_ERR"; + break; + case RFS_ERR: + resultCodeString = "RFS_ERR"; + break; + case ACT_ERR: + resultCodeString = "ACT_ERR"; + break; + case CFT_ERR: + resultCodeString = "CFT_ERR"; + break; + default: + resultCodeString = "0x" + Hexdump.toHexString( resultCode, 1 ); + break; + } + switch( questionType ) { + case NB: + questionTypeString = "NB"; + break; + case NBSTAT: + questionTypeString = "NBSTAT"; + break; + default: + questionTypeString = "0x" + Hexdump.toHexString( questionType, 4 ); + break; + } + switch( recordType ) { + case A: + recordTypeString = "A"; + break; + case NS: + recordTypeString = "NS"; + break; + case NULL: + recordTypeString = "NULL"; + break; + case NB: + recordTypeString = "NB"; + break; + case NBSTAT: + recordTypeString = "NBSTAT"; + break; + default: + recordTypeString = "0x" + Hexdump.toHexString( recordType, 4 ); + break; + } + + return new String( + "nameTrnId=" + nameTrnId + + ",isResponse=" + isResponse + + ",opCode=" + opCodeString + + ",isAuthAnswer=" + isAuthAnswer + + ",isTruncated=" + isTruncated + + ",isRecurAvailable=" + isRecurAvailable + + ",isRecurDesired=" + isRecurDesired + + ",isBroadcast=" + isBroadcast + + ",resultCode=" + resultCode + + ",questionCount=" + questionCount + + ",answerCount=" + answerCount + + ",authorityCount=" + authorityCount + + ",additionalCount=" + additionalCount + + ",questionName=" + questionName + + ",questionType=" + questionTypeString + + ",questionClass=" + ( questionClass == IN ? "IN" : + "0x" + Hexdump.toHexString( questionClass, 4 )) + + ",recordName=" + recordName + + ",recordType=" + recordTypeString + + ",recordClass=" + ( recordClass == IN ? "IN" : + "0x" + Hexdump.toHexString( recordClass, 4 )) + + ",ttl=" + ttl + + ",rDataLength=" + rDataLength ); + } +} + diff --git a/src/jcifs/netbios/NbtAddress.java b/src/jcifs/netbios/NbtAddress.java new file mode 100644 index 0000000..0e19ff6 --- /dev/null +++ b/src/jcifs/netbios/NbtAddress.java @@ -0,0 +1,879 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.net.SocketException; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import jcifs.Config; +import jcifs.util.Hexdump; + +/** + * This class represents a NetBIOS over TCP/IP address. Under normal + * conditions, users of jCIFS need not be concerned with this class as + * name resolution and session services are handled internally by the smb package. + * + *

Applications can use the methods getLocalHost, + * getByName, and + * getAllByAddress to create a new NbtAddress instance. This + * class is symmetric with {@link java.net.InetAddress}. + * + *

About NetBIOS: The NetBIOS name + * service is a dynamic distributed service that allows hosts to resolve + * names by broadcasting a query, directing queries to a server such as + * Samba or WINS. NetBIOS is currently the primary networking layer for + * providing name service, datagram service, and session service to the + * Microsoft Windows platform. A NetBIOS name can be 15 characters long + * and hosts usually registers several names on the network. From a + * Windows command prompt you can see + * what names a host registers with the nbtstat command. + *

+ * C:\>nbtstat -a 192.168.1.15
+ * 
+ *        NetBIOS Remote Machine Name Table
+ * 
+ *    Name               Type         Status
+ * ---------------------------------------------
+ * JMORRIS2        <00>  UNIQUE      Registered
+ * BILLING-NY      <00>  GROUP       Registered
+ * JMORRIS2        <03>  UNIQUE      Registered
+ * JMORRIS2        <20>  UNIQUE      Registered
+ * BILLING-NY      <1E>  GROUP       Registered
+ * JMORRIS         <03>  UNIQUE      Registered
+ * 
+ * MAC Address = 00-B0-34-21-FA-3B
+ * 
+ *

The hostname of this machine is JMORRIS2. It is + * a member of the group(a.k.a workgroup and domain) BILLING-NY. To + * obtain an {@link java.net.InetAddress} for a host one might do: + * + *

+ *   InetAddress addr = NbtAddress.getByName( "jmorris2" ).getInetAddress();
+ * 
+ *

From a UNIX platform with Samba installed you can perform similar + * diagnostics using the nmblookup utility. + * + * @author Michael B. Allen + * @see java.net.InetAddress + * @since jcifs-0.1 + */ + +public final class NbtAddress { + +/* + * This is a special name that means all hosts. If you wish to find all hosts + * on a network querying a workgroup group name is the preferred method. + */ + + static final String ANY_HOSTS_NAME = "*\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"; + +/** + * This is a special name for querying the master browser that serves the + * list of hosts found in "Network Neighborhood". + */ + + public static final String MASTER_BROWSER_NAME = "\u0001\u0002__MSBROWSE__\u0002"; + +/** + * A special generic name specified when connecting to a host for which + * a name is not known. Not all servers respond to this name. + */ + + public static final String SMBSERVER_NAME = "*SMBSERVER "; + +/** + * A B node only broadcasts name queries. This is the default if a + * nameserver such as WINS or Samba is not specified. + */ + + public static final int B_NODE = 0; + +/** + * A Point-to-Point node, or P node, unicasts queries to a nameserver + * only. Natrually the jcifs.netbios.nameserver property must + * be set. + */ + + public static final int P_NODE = 1; + +/** + * Try Broadcast queries first, then try to resolve the name using the + * nameserver. + */ + + public static final int M_NODE = 2; + +/** + * A Hybrid node tries to resolve a name using the nameserver first. If + * that fails use the broadcast address. This is the default if a nameserver + * is provided. This is the behavior of Microsoft Windows machines. + */ + + public static final int H_NODE = 3; + + static final InetAddress[] NBNS = Config.getInetAddressArray( "jcifs.netbios.wins", ",", new InetAddress[0] ); + + /* Construct the shared static client object that will + * conduct all encoding and decoding of NetBIOS name service + * messages as well as socket IO in a synchronized fashon. + */ + + private static final NameServiceClient CLIENT = new NameServiceClient(); + + private static final int DEFAULT_CACHE_POLICY = 30; + private static final int CACHE_POLICY = Config.getInt( "jcifs.netbios.cachePolicy", DEFAULT_CACHE_POLICY ); + private static final int FOREVER = -1; + private static int nbnsIndex = 0; + + private static final HashMap ADDRESS_CACHE = new HashMap(); + private static final HashMap LOOKUP_TABLE = new HashMap(); + + static final Name UNKNOWN_NAME = new Name( "0.0.0.0", 0x00, null ); + static final NbtAddress UNKNOWN_ADDRESS = new NbtAddress( UNKNOWN_NAME, 0, false, B_NODE ); + static final byte[] UNKNOWN_MAC_ADDRESS = new byte[] { + (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00 + }; + + static final class CacheEntry { + Name hostName; + NbtAddress address; + long expiration; + + CacheEntry( Name hostName, NbtAddress address, long expiration ) { + this.hostName = hostName; + this.address = address; + this.expiration = expiration; + } + } + + static NbtAddress localhost; + + static { + InetAddress localInetAddress; + String localHostname; + Name localName; + + /* Create an address to represent failed lookups and cache forever. + */ + + ADDRESS_CACHE.put( UNKNOWN_NAME, new CacheEntry( UNKNOWN_NAME, UNKNOWN_ADDRESS, FOREVER )); + + /* Determine the InetAddress of the local interface + * if one was not specified. + */ + localInetAddress = CLIENT.laddr; + if( localInetAddress == null ) { + try { + localInetAddress = InetAddress.getLocalHost(); + } catch( UnknownHostException uhe ) { + /* Java cannot determine the localhost. This is basically a config + * issue on the host. There's not much we can do about it. Just + * to suppress NPEs that would result we can create a possibly bogus + * address. Pretty sure the below cannot actually thrown a UHE tho. + */ + try { + localInetAddress = InetAddress.getByName("127.0.0.1"); + } catch( UnknownHostException ignored ) { + } + } + } + + /* If a local hostname was not provided a name like + * JCIFS34_172_A6 will be dynamically generated for the + * client. This is primarily (exclusively?) used as a + * CallingName during session establishment. + */ + localHostname = Config.getProperty( "jcifs.netbios.hostname", null ); + if( localHostname == null || localHostname.length() == 0 ) { + byte[] addr = localInetAddress.getAddress(); + localHostname = "JCIFS" + + ( addr[2] & 0xFF ) + "_" + + ( addr[3] & 0xFF ) + "_" + + Hexdump.toHexString( (int)( Math.random() * (double)0xFF ), 2 ); + } + + /* Create an NbtAddress for the local interface with + * the name deduced above possibly with scope applied and + * cache it forever. + */ + localName = new Name( localHostname, 0x00, + Config.getProperty( "jcifs.netbios.scope", null )); + localhost = new NbtAddress( localName, + localInetAddress.hashCode(), + false, + B_NODE, + false, false, true, false, + UNKNOWN_MAC_ADDRESS ); + cacheAddress( localName, localhost, FOREVER ); + } + + static void cacheAddress( Name hostName, NbtAddress addr ) { + if( CACHE_POLICY == 0 ) { + return; + } + long expiration = -1; + if( CACHE_POLICY != FOREVER ) { + expiration = System.currentTimeMillis() + CACHE_POLICY * 1000; + } + cacheAddress( hostName, addr, expiration ); + } + static void cacheAddress( Name hostName, NbtAddress addr, long expiration ) { + if( CACHE_POLICY == 0 ) { + return; + } + synchronized( ADDRESS_CACHE ) { + CacheEntry entry = (CacheEntry)ADDRESS_CACHE.get( hostName ); + if( entry == null ) { + entry = new CacheEntry( hostName, addr, expiration ); + ADDRESS_CACHE.put( hostName, entry ); + } else { + entry.address = addr; + entry.expiration = expiration; + } + } + } + static void cacheAddressArray( NbtAddress[] addrs ) { + if( CACHE_POLICY == 0 ) { + return; + } + long expiration = -1; + if( CACHE_POLICY != FOREVER ) { + expiration = System.currentTimeMillis() + CACHE_POLICY * 1000; + } + synchronized( ADDRESS_CACHE ) { + for( int i = 0; i < addrs.length; i++ ) { + CacheEntry entry = (CacheEntry)ADDRESS_CACHE.get( addrs[i].hostName ); + if( entry == null ) { + entry = new CacheEntry( addrs[i].hostName, addrs[i], expiration ); + ADDRESS_CACHE.put( addrs[i].hostName, entry ); + } else { + entry.address = addrs[i]; + entry.expiration = expiration; + } + } + } + } + static NbtAddress getCachedAddress( Name hostName ) { + if( CACHE_POLICY == 0 ) { + return null; + } + synchronized( ADDRESS_CACHE ) { + CacheEntry entry = (CacheEntry)ADDRESS_CACHE.get( hostName ); + if( entry != null && entry.expiration < System.currentTimeMillis() && + entry.expiration >= 0 ) { + entry = null; + } + return entry != null ? entry.address : null; + } + } + + static NbtAddress doNameQuery( Name name, InetAddress svr ) + throws UnknownHostException { + NbtAddress addr; + + if( name.hexCode == 0x1d && svr == null ) { + svr = CLIENT.baddr; // bit of a hack but saves a lookup + } + name.srcHashCode = svr != null ? svr.hashCode() : 0; + addr = getCachedAddress( name ); + + if( addr == null ) { + /* This was copied amost verbatim from InetAddress.java. See the + * comments there for a description of how the LOOKUP_TABLE prevents + * redundant queries from going out on the wire. + */ + if(( addr = (NbtAddress)checkLookupTable( name )) == null ) { + try { + addr = CLIENT.getByName( name, svr ); + } catch( UnknownHostException uhe ) { + addr = UNKNOWN_ADDRESS; + } finally { + cacheAddress( name, addr ); + updateLookupTable( name ); + } + } + } + if( addr == UNKNOWN_ADDRESS ) { + throw new UnknownHostException( name.toString() ); + } + return addr; + } + + private static Object checkLookupTable( Name name ) { + Object obj; + + synchronized( LOOKUP_TABLE ) { + if( LOOKUP_TABLE.containsKey( name ) == false ) { + LOOKUP_TABLE.put( name, name ); + return null; + } + while( LOOKUP_TABLE.containsKey( name )) { + try { + LOOKUP_TABLE.wait(); + } catch( InterruptedException e ) { + } + } + } + obj = getCachedAddress( name ); + if( obj == null ) { + synchronized( LOOKUP_TABLE ) { + LOOKUP_TABLE.put( name, name ); + } + } + + return obj; + } + private static void updateLookupTable( Name name ) { + synchronized( LOOKUP_TABLE ) { + LOOKUP_TABLE.remove( name ); + LOOKUP_TABLE.notifyAll(); + } + } + +/** + * Retrieves the local host address. + * + * @throws UnknownHostException This is not likely as the IP returned + * by InetAddress should be available + */ + + public static NbtAddress getLocalHost() throws UnknownHostException { + return localhost; + } + public static Name getLocalName() { + return localhost.hostName; + } + +/** + * Determines the address of a host given it's host name. The name can be a NetBIOS name like + * "freto" or an IP address like "192.168.1.15". It cannot be a DNS name; + * the analygous {@link jcifs.UniAddress} or {@link java.net.InetAddress} + * getByName methods can be used for that. + * + * @param host hostname to resolve + * @throws java.net.UnknownHostException if there is an error resolving the name + */ + + public static NbtAddress getByName( String host ) + throws UnknownHostException { + return getByName( host, 0x00, null ); + } + +/** + * Determines the address of a host given it's host name. NetBIOS + * names also have a type. Types(aka Hex Codes) + * are used to distiquish the various services on a host. Here is + * a fairly complete list of NetBIOS hex codes. Scope is not used but is + * still functional in other NetBIOS products and so for completeness it has been + * implemented. A scope of null or "" + * signifies no scope. + * + * @param host the name to resolve + * @param type the hex code of the name + * @param scope the scope of the name + * @throws java.net.UnknownHostException if there is an error resolving the name + */ + + public static NbtAddress getByName( String host, + int type, + String scope ) + throws UnknownHostException { + + return getByName( host, type, scope, null ); + } + +/* + * The additional svr parameter specifies the address to + * query. This might be the address of a specific host, a name server, + * or a broadcast address. + */ + + public static NbtAddress getByName( String host, + int type, + String scope, + InetAddress svr ) + throws UnknownHostException { + + if( host == null || host.length() == 0 ) { + return getLocalHost(); + } + if( !Character.isDigit( host.charAt(0) )) { + return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr ); + } else { + int IP = 0x00; + int hitDots = 0; + char[] data = host.toCharArray(); + + for( int i = 0; i < data.length; i++ ) { + char c = data[i]; + if( c < 48 || c > 57 ) { + return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr ); + } + int b = 0x00; + while( c != '.' ) { + if( c < 48 || c > 57 ) { + return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr ); + } + b = b * 10 + c - '0'; + + if( ++i >= data.length ) + break; + + c = data[i]; + } + if( b > 0xFF ) { + return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr ); + } + IP = ( IP << 8 ) + b; + hitDots++; + } + if( hitDots != 4 || host.endsWith( "." )) { + return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr ); + } + return new NbtAddress( UNKNOWN_NAME, IP, false, B_NODE ); + } + } + + public static NbtAddress[] getAllByName( String host, + int type, + String scope, + InetAddress svr ) + throws UnknownHostException { + return CLIENT.getAllByName( new Name( host, type, scope ), svr ); + } + +/** + * Retrieve all addresses of a host by it's address. NetBIOS hosts can + * have many names for a given IP address. The name and IP address make the + * NetBIOS address. This provides a way to retrieve the other names for a + * host with the same IP address. + * + * @param host hostname to lookup all addresses for + * @throws java.net.UnknownHostException if there is an error resolving the name + */ + + + public static NbtAddress[] getAllByAddress( String host ) + throws UnknownHostException { + return getAllByAddress( getByName( host, 0x00, null )); + } + + +/** + * Retrieve all addresses of a host by it's address. NetBIOS hosts can + * have many names for a given IP address. The name and IP address make + * the NetBIOS address. This provides a way to retrieve the other names + * for a host with the same IP address. See {@link #getByName} + * for a description of type + * and scope. + * + * @param host hostname to lookup all addresses for + * @param type the hexcode of the name + * @param scope the scope of the name + * @throws java.net.UnknownHostException if there is an error resolving the name + */ + + + public static NbtAddress[] getAllByAddress( String host, + int type, + String scope ) + throws UnknownHostException { + return getAllByAddress( getByName( host, type, scope )); + } + + +/** + * Retrieve all addresses of a host by it's address. NetBIOS hosts can + * have many names for a given IP address. The name and IP address make the + * NetBIOS address. This provides a way to retrieve the other names for a + * host with the same IP address. + * + * @param addr the address to query + * @throws UnknownHostException if address cannot be resolved + */ + + public static NbtAddress[] getAllByAddress( NbtAddress addr ) + throws UnknownHostException { + try { + NbtAddress[] addrs = CLIENT.getNodeStatus( addr ); + cacheAddressArray( addrs ); + return addrs; + } catch( UnknownHostException uhe ) { + throw new UnknownHostException( "no name with type 0x" + + Hexdump.toHexString( addr.hostName.hexCode, 2 ) + + ((( addr.hostName.scope == null ) || + ( addr.hostName.scope.length() == 0 )) ? + " with no scope" : " with scope " + addr.hostName.scope ) + + " for host " + addr.getHostAddress() ); + } + } + + public static InetAddress getWINSAddress() { + return NBNS.length == 0 ? null : NBNS[nbnsIndex]; + } + public static boolean isWINS( InetAddress svr ) { + for( int i = 0; svr != null && i < NBNS.length; i++ ) { + if( svr.hashCode() == NBNS[i].hashCode() ) { + return true; + } + } + return false; + } + static InetAddress switchWINS() { + nbnsIndex = (nbnsIndex + 1) < NBNS.length ? nbnsIndex + 1 : 0; + return NBNS.length == 0 ? null : NBNS[nbnsIndex]; + } + + Name hostName; + int address, nodeType; + boolean groupName, + isBeingDeleted, + isInConflict, + isActive, + isPermanent, + isDataFromNodeStatus; + byte[] macAddress; + String calledName; + + NbtAddress( Name hostName, int address, boolean groupName, int nodeType ) { + this.hostName = hostName; + this.address = address; + this.groupName = groupName; + this.nodeType = nodeType; + } + + NbtAddress( Name hostName, + int address, + boolean groupName, + int nodeType, + boolean isBeingDeleted, + boolean isInConflict, + boolean isActive, + boolean isPermanent, + byte[] macAddress ) { + +/* The NodeStatusResponse.readNodeNameArray method may also set this + * information. These two places where node status data is populated should + * be consistent. Be carefull! + */ + this.hostName = hostName; + this.address = address; + this.groupName = groupName; + this.nodeType = nodeType; + this.isBeingDeleted = isBeingDeleted; + this.isInConflict = isInConflict; + this.isActive = isActive; + this.isPermanent = isPermanent; + this.macAddress = macAddress; + isDataFromNodeStatus = true; + } + +/* Guess next called name to try for session establishment. These + * methods are used by the smb package. + */ + + public String firstCalledName() { + + calledName = hostName.name; + + if( Character.isDigit( calledName.charAt( 0 ))) { + int i, len, dots; + char[] data; + + i = dots = 0; /* quick IP address validation */ + len = calledName.length(); + data = calledName.toCharArray(); + while( i < len && Character.isDigit( data[i++] )) { + if( i == len && dots == 3 ) { + // probably an IP address + calledName = SMBSERVER_NAME; + break; + } + if( i < len && data[i] == '.' ) { + dots++; + i++; + } + } + } else { + switch (hostName.hexCode) { + case 0x1B: + case 0x1C: + case 0x1D: + calledName = SMBSERVER_NAME; + } + } + + return calledName; + } + public String nextCalledName() { + + if( calledName == hostName.name ) { + calledName = SMBSERVER_NAME; + } else if( calledName == SMBSERVER_NAME ) { + NbtAddress[] addrs; + + try { + addrs = CLIENT.getNodeStatus( this ); + if( hostName.hexCode == 0x1D ) { + for( int i = 0; i < addrs.length; i++ ) { + if( addrs[i].hostName.hexCode == 0x20 ) { + return addrs[i].hostName.name; + } + } + return null; + } else if( isDataFromNodeStatus ) { + /* 'this' has been updated and should now + * have a real NetBIOS name + */ + calledName = null; + return hostName.name; + } + } catch( UnknownHostException uhe ) { + calledName = null; + } + } else { + calledName = null; + } + + return calledName; + } + +/* + * There are three degrees of state that any NbtAddress can have. + * + * 1) IP Address - If a dot-quad IP string is used with getByName (or used + * to create an NbtAddress internal to this netbios package), no query is + * sent on the wire and the only state this object has is it's IP address + * (but that's enough to connect to a host using *SMBSERVER for CallingName). + * + * 2) IP Address, NetBIOS name, nodeType, groupName - If however a + * legal NetBIOS name string is used a name query request will retreive + * the IP, node type, and whether or not this NbtAddress represents a + * group name. This degree of state can be obtained with a Name Query + * Request or Node Status Request. + * + * 3) All - The NbtAddress will be populated with all state such as mac + * address, isPermanent, isBeingDeleted, ...etc. This information can only + * be retrieved with the Node Status request. + * + * The degree of state that an NbtAddress has is dependant on how it was + * created and what is required of it. The second degree of state is the + * most common. This is the state information that would be retrieved from + * WINS for example. Natrually it is not practical for every NbtAddress + * to be populated will all state requiring a Node Status on every host + * encountered. The below methods allow state to be populated when requested + * in a lazy fashon. + */ + + void checkData() throws UnknownHostException { + if( hostName == UNKNOWN_NAME ) { + getAllByAddress( this ); + } + } + void checkNodeStatusData() throws UnknownHostException { + if( isDataFromNodeStatus == false ) { + getAllByAddress( this ); + } + } + +/** + * Determines if the address is a group address. This is also + * known as a workgroup name or group name. + * + * @throws UnknownHostException if the host cannot be resolved to find out. + */ + + public boolean isGroupAddress() throws UnknownHostException { + checkData(); + return groupName; + } + +/** + * Checks the node type of this address. + * @return {@link jcifs.netbios.NbtAddress#B_NODE}, + * {@link jcifs.netbios.NbtAddress#P_NODE}, {@link jcifs.netbios.NbtAddress#M_NODE}, + * {@link jcifs.netbios.NbtAddress#H_NODE} + * + * @throws UnknownHostException if the host cannot be resolved to find out. + */ + + public int getNodeType() throws UnknownHostException { + checkData(); + return nodeType; + } + +/** + * Determines if this address in the process of being deleted. + * + * @throws UnknownHostException if the host cannot be resolved to find out. + */ + + public boolean isBeingDeleted() throws UnknownHostException { + checkNodeStatusData(); + return isBeingDeleted; + } + +/** + * Determines if this address in conflict with another address. + * + * @throws UnknownHostException if the host cannot be resolved to find out. + */ + + public boolean isInConflict() throws UnknownHostException { + checkNodeStatusData(); + return isInConflict; + } + +/** + * Determines if this address is active. + * + * @throws UnknownHostException if the host cannot be resolved to find out. + */ + + public boolean isActive() throws UnknownHostException { + checkNodeStatusData(); + return isActive; + } + +/** + * Determines if this address is set to be permanent. + * + * @throws UnknownHostException if the host cannot be resolved to find out. + */ + + public boolean isPermanent() throws UnknownHostException { + checkNodeStatusData(); + return isPermanent; + } + +/** + * Retrieves the MAC address of the remote network interface. Samba returns all zeros. + * + * @return the MAC address as an array of six bytes + * @throws UnknownHostException if the host cannot be resolved to + * determine the MAC address. + */ + + public byte[] getMacAddress() throws UnknownHostException { + checkNodeStatusData(); + return macAddress; + } + +/** + * The hostname of this address. If the hostname is null the local machines + * IP address is returned. + * + * @return the text representation of the hostname associated with this address + */ + + public String getHostName() { + /* 2010 - We no longer try a Node Status to get the + * hostname because apparently some servers do not respond + * anymore. I think everyone post Windows 98 will accept + * an IP address as the tconHostName which is the principal + * use of this method. + */ + if (hostName == UNKNOWN_NAME) { + return getHostAddress(); + } + return hostName.name; + } + + +/** + * Returns the raw IP address of this NbtAddress. The result is in network + * byte order: the highest order byte of the address is in getAddress()[0]. + * + * @return a four byte array + */ + + public byte[] getAddress() { + byte[] addr = new byte[4]; + + addr[0] = (byte)(( address >>> 24 ) & 0xFF ); + addr[1] = (byte)(( address >>> 16 ) & 0xFF ); + addr[2] = (byte)(( address >>> 8 ) & 0xFF ); + addr[3] = (byte)( address & 0xFF ); + return addr; + } + +/** + * To convert this address to an InetAddress. + * + * @return the {@link java.net.InetAddress} representation of this address. + */ + + public InetAddress getInetAddress() throws UnknownHostException { + return InetAddress.getByName( getHostAddress() ); + } + +/** + * Returns this IP adress as a {@link java.lang.String} in the form "%d.%d.%d.%d". + */ + + public String getHostAddress() { + return (( address >>> 24 ) & 0xFF ) + "." + + (( address >>> 16 ) & 0xFF ) + "." + + (( address >>> 8 ) & 0xFF ) + "." + + (( address >>> 0 ) & 0xFF ); + } + +/** + * Returned the hex code associated with this name(e.g. 0x20 is for the file service) + */ + + public int getNameType() { + return hostName.hexCode; + } + +/** + * Returns a hashcode for this IP address. The hashcode comes from the IP address + * and is not generated from the string representation. So because NetBIOS nodes + * can have many names, all names associated with an IP will have the same + * hashcode. + */ + + public int hashCode() { + return address; + } + +/** + * Determines if this address is equal two another. Only the IP Addresses + * are compared. Similar to the {@link #hashCode} method, the comparison + * is based on the integer IP address and not the string representation. + */ + + public boolean equals( Object obj ) { + return ( obj != null ) && ( obj instanceof NbtAddress ) && + ( ((NbtAddress)obj).address == address ); + } + +/** + * Returns the {@link java.lang.String} representaion of this address. + */ + + public String toString() { + return hostName.toString() + "/" + getHostAddress(); + } +} diff --git a/src/jcifs/netbios/NbtException.java b/src/jcifs/netbios/NbtException.java new file mode 100644 index 0000000..7f18127 --- /dev/null +++ b/src/jcifs/netbios/NbtException.java @@ -0,0 +1,103 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.io.IOException; + +public class NbtException extends IOException { + + // error classes + public static final int SUCCESS = 0; + public static final int ERR_NAM_SRVC = 0x01; + public static final int ERR_SSN_SRVC = 0x02; + + // name service error codes + public static final int FMT_ERR = 0x1; + public static final int SRV_ERR = 0x2; + public static final int IMP_ERR = 0x4; + public static final int RFS_ERR = 0x5; + public static final int ACT_ERR = 0x6; + public static final int CFT_ERR = 0x7; + + // session service error codes + public static final int CONNECTION_REFUSED = -1; + public static final int NOT_LISTENING_CALLED = 0x80; + public static final int NOT_LISTENING_CALLING = 0x81; + public static final int CALLED_NOT_PRESENT = 0x82; + public static final int NO_RESOURCES = 0x83; + public static final int UNSPECIFIED = 0x8F; + + public int errorClass; + public int errorCode; + + public static String getErrorString( int errorClass, int errorCode ) { + String result = ""; + switch( errorClass ) { + case SUCCESS: + result += "SUCCESS"; + break; + case ERR_NAM_SRVC: + result += "ERR_NAM_SRVC/"; + switch( errorCode ) { + case FMT_ERR: + result += "FMT_ERR: Format Error"; + default: + result += "Unknown error code: " + errorCode; + } + break; + case ERR_SSN_SRVC: + result += "ERR_SSN_SRVC/"; + switch( errorCode ) { + case CONNECTION_REFUSED: + result += "Connection refused"; + break; + case NOT_LISTENING_CALLED: + result += "Not listening on called name"; + break; + case NOT_LISTENING_CALLING: + result += "Not listening for calling name"; + break; + case CALLED_NOT_PRESENT: + result += "Called name not present"; + break; + case NO_RESOURCES: + result += "Called name present, but insufficient resources"; + break; + case UNSPECIFIED: + result += "Unspecified error"; + break; + default: + result += "Unknown error code: " + errorCode; + } + break; + default: + result += "unknown error class: " + errorClass; + } + return result; + } + + public NbtException( int errorClass, int errorCode ) { + super( getErrorString( errorClass, errorCode )); + this.errorClass = errorClass; + this.errorCode = errorCode; + } + public String toString() { + return new String( "errorClass=" + errorClass + ",errorCode=" + errorCode + ",errorString=" + getErrorString( errorClass, errorCode )); + } +} diff --git a/src/jcifs/netbios/NbtSocket.java b/src/jcifs/netbios/NbtSocket.java new file mode 100644 index 0000000..0efcff5 --- /dev/null +++ b/src/jcifs/netbios/NbtSocket.java @@ -0,0 +1,134 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.net.Socket; +import java.net.InetAddress; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; +import jcifs.Config; +import jcifs.util.LogStream; + +/** +Do not use this class. Writing to the OutputStream of this type of socket +requires leaving a 4 byte prefix for the NBT header. IOW you must call +write( buf, 4, len ). Calling write( buf, 0, len ) will generate an error. + */ + +public class NbtSocket extends Socket { + + private static final int SSN_SRVC_PORT = 139; + private static final int BUFFER_SIZE = 512; + private static final int DEFAULT_SO_TIMEOUT = 5000; + + private static LogStream log = LogStream.getInstance(); + + private NbtAddress address; + private Name calledName; + private int soTimeout; + + public NbtSocket() { + super(); + } + public NbtSocket( NbtAddress address, int port ) throws IOException { + this( address, port, null, 0 ); + } + public NbtSocket( NbtAddress address, int port, + InetAddress localAddr, int localPort ) throws IOException { + this( address, null, port, localAddr, localPort ); + } + public NbtSocket( NbtAddress address, String calledName, int port, + InetAddress localAddr, int localPort ) throws IOException { + super( address.getInetAddress(), ( port == 0 ? SSN_SRVC_PORT : port ), + localAddr, localPort ); + this.address = address; + if( calledName == null ) { + this.calledName = address.hostName; + } else { + this.calledName = new Name( calledName, 0x20, null ); + } + soTimeout = Config.getInt( "jcifs.netbios.soTimeout", DEFAULT_SO_TIMEOUT ); + connect(); + } + + public NbtAddress getNbtAddress() { + return address; + } + public InputStream getInputStream() throws IOException { + return new SocketInputStream( super.getInputStream() ); + } + public OutputStream getOutputStream() throws IOException { + return new SocketOutputStream( super.getOutputStream() ); + } + public int getPort() { + return super.getPort(); + } + public InetAddress getLocalAddress() { + return super.getLocalAddress(); + } + public int getLocalPort() { + return super.getLocalPort(); + } + public String toString() { + return "NbtSocket[addr=" + address + + ",port=" + super.getPort() + + ",localport=" + super.getLocalPort() + "]"; + } + private void connect() throws IOException { + byte[] buffer = new byte[BUFFER_SIZE]; + int type; + InputStream in; + + try { + in = super.getInputStream(); + OutputStream out = super.getOutputStream(); + + SessionServicePacket ssp0 = new SessionRequestPacket( calledName, NbtAddress.localhost.hostName ); + out.write( buffer, 0, ssp0.writeWireFormat( buffer, 0 )); + + setSoTimeout( soTimeout ); + type = ssp0.readPacketType( in, buffer, 0 ); + } catch( IOException ioe ) { + close(); + throw ioe; + } + + switch( type ) { + case SessionServicePacket.POSITIVE_SESSION_RESPONSE: + if( log.level > 2 ) + log.println( "session established ok with " + address ); + return; + case SessionServicePacket.NEGATIVE_SESSION_RESPONSE: + int errorCode = (int)( in.read() & 0xFF ); + close(); + throw new NbtException( NbtException.ERR_SSN_SRVC, errorCode ); + case -1: + throw new NbtException( NbtException.ERR_SSN_SRVC, NbtException.CONNECTION_REFUSED ); + default: + close(); + throw new NbtException( NbtException.ERR_SSN_SRVC, 0 ); + } + } + public void close() throws IOException { + if( log.level > 3 ) + log.println( "close: " + this ); + super.close(); + } +} diff --git a/src/jcifs/netbios/NodeStatusRequest.java b/src/jcifs/netbios/NodeStatusRequest.java new file mode 100644 index 0000000..fb3a9b5 --- /dev/null +++ b/src/jcifs/netbios/NodeStatusRequest.java @@ -0,0 +1,50 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +class NodeStatusRequest extends NameServicePacket { + + NodeStatusRequest( Name name ) { + questionName = name; + questionType = NBSTAT; + isRecurDesired = false; + isBroadcast = false; + } + + int writeBodyWireFormat( byte[] dst, int dstIndex ) { + int tmp = questionName.hexCode; + questionName.hexCode = 0x00; // type has to be 0x00 for node status + int result = writeQuestionSectionWireFormat( dst, dstIndex ); + questionName.hexCode = tmp; + return result; + } + int readBodyWireFormat( byte[] src, int srcIndex ) { + return 0; + } + int writeRDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readRDataWireFormat( byte[] src, int srcIndex ) { + return 0; + } + public String toString() { + return new String( "NodeStatusRequest[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/netbios/NodeStatusResponse.java b/src/jcifs/netbios/NodeStatusResponse.java new file mode 100644 index 0000000..3b71f1b --- /dev/null +++ b/src/jcifs/netbios/NodeStatusResponse.java @@ -0,0 +1,144 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.io.UnsupportedEncodingException; + +class NodeStatusResponse extends NameServicePacket { + + private NbtAddress queryAddress; + + private int numberOfNames; + private byte[] macAddress; + private byte[] stats; + + NbtAddress[] addressArray; + + /* It is a little awkward but prudent to pass the quering address + * so that it may be included in the list of results. IOW we do + * not want to create a new NbtAddress object for this particular + * address from which the query is constructed, we want to populate + * the data of the existing address that should be one of several + * returned by the node status. + */ + + NodeStatusResponse( NbtAddress queryAddress ) { + this.queryAddress = queryAddress; + recordName = new Name(); + macAddress = new byte[6]; + } + + int writeBodyWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readBodyWireFormat( byte[] src, int srcIndex ) { + return readResourceRecordWireFormat( src, srcIndex ); + } + int writeRDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readRDataWireFormat( byte[] src, int srcIndex ) { + int start = srcIndex; + numberOfNames = src[srcIndex] & 0xFF; + int namesLength = numberOfNames * 18; + int statsLength = rDataLength - namesLength - 1; + numberOfNames = src[srcIndex++] & 0xFF; + // gotta read the mac first so we can populate addressArray with it + System.arraycopy( src, srcIndex + namesLength, macAddress, 0, 6 ); + srcIndex += readNodeNameArray( src, srcIndex ); + stats = new byte[statsLength]; + System.arraycopy( src, srcIndex, stats, 0, statsLength ); + srcIndex += statsLength; + return srcIndex - start; + } + private int readNodeNameArray( byte[] src, int srcIndex ) { + int start = srcIndex; + + addressArray = new NbtAddress[numberOfNames]; + + String n; + int hexCode; + String scope = queryAddress.hostName.scope; + boolean groupName; + int ownerNodeType; + boolean isBeingDeleted; + boolean isInConflict; + boolean isActive; + boolean isPermanent; + int j; + boolean addrFound = false; + + try { + for( int i = 0; i < numberOfNames; srcIndex += 18, i++ ) { + for( j = srcIndex + 14; src[j] == 0x20; j-- ) + ; + n = new String( src, srcIndex, j - srcIndex + 1, Name.OEM_ENCODING ); + hexCode = src[srcIndex + 15] & 0xFF; + groupName = (( src[srcIndex + 16] & 0x80 ) == 0x80 ) ? true : false; + ownerNodeType = ( src[srcIndex + 16] & 0x60 ) >> 5; + isBeingDeleted = (( src[srcIndex + 16] & 0x10 ) == 0x10 ) ? true : false; + isInConflict = (( src[srcIndex + 16] & 0x08 ) == 0x08 ) ? true : false; + isActive = (( src[srcIndex + 16] & 0x04 ) == 0x04 ) ? true : false; + isPermanent = (( src[srcIndex + 16] & 0x02 ) == 0x02 ) ? true : false; + + /* The NbtAddress object used to query this node will be in the list + * returned by the Node Status. A new NbtAddress object should not be + * created for it because the original is potentially being actively + * referenced by other objects. We must populate the existing object's + * data explicitly (and carefully). + */ + if( !addrFound && queryAddress.hostName.hexCode == hexCode && + ( queryAddress.hostName == NbtAddress.UNKNOWN_NAME || + queryAddress.hostName.name.equals( n ))) { + + if( queryAddress.hostName == NbtAddress.UNKNOWN_NAME ) { + queryAddress.hostName = new Name( n, hexCode, scope ); + } + queryAddress.groupName = groupName; + queryAddress.nodeType = ownerNodeType; + queryAddress.isBeingDeleted = isBeingDeleted; + queryAddress.isInConflict = isInConflict; + queryAddress.isActive = isActive; + queryAddress.isPermanent = isPermanent; + queryAddress.macAddress = macAddress; + queryAddress.isDataFromNodeStatus = true; + addrFound = true; + addressArray[i] = queryAddress; + } else { + addressArray[i] = new NbtAddress( new Name( n, hexCode, scope ), + queryAddress.address, + groupName, + ownerNodeType, + isBeingDeleted, + isInConflict, + isActive, + isPermanent, + macAddress ); + } + } + } catch( UnsupportedEncodingException uee ) { + } + return srcIndex - start; + } + public String toString() { + return new String( "NodeStatusResponse[" + + super.toString() + "]" ); + } +} + diff --git a/src/jcifs/netbios/SessionRequestPacket.java b/src/jcifs/netbios/SessionRequestPacket.java new file mode 100644 index 0000000..e312df4 --- /dev/null +++ b/src/jcifs/netbios/SessionRequestPacket.java @@ -0,0 +1,55 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.io.IOException; +import java.io.InputStream; + +public class SessionRequestPacket extends SessionServicePacket { + + private Name calledName, callingName; + + SessionRequestPacket() { + calledName = new Name(); + callingName = new Name(); + } + public SessionRequestPacket( Name calledName, Name callingName ) { + type = SESSION_REQUEST; + this.calledName = calledName; + this.callingName = callingName; + } + int writeTrailerWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + dstIndex += calledName.writeWireFormat( dst, dstIndex ); + dstIndex += callingName.writeWireFormat( dst, dstIndex ); + return dstIndex - start; + } + int readTrailerWireFormat( InputStream in, + byte[] buffer, + int bufferIndex ) + throws IOException { + int start = bufferIndex; + if( in.read( buffer, bufferIndex, length ) != length ) { + throw new IOException( "invalid session request wire format" ); + } + bufferIndex += calledName.readWireFormat( buffer, bufferIndex ); + bufferIndex += callingName.readWireFormat( buffer, bufferIndex ); + return bufferIndex - start; + } +} diff --git a/src/jcifs/netbios/SessionRetargetResponsePacket.java b/src/jcifs/netbios/SessionRetargetResponsePacket.java new file mode 100644 index 0000000..36c8913 --- /dev/null +++ b/src/jcifs/netbios/SessionRetargetResponsePacket.java @@ -0,0 +1,50 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.io.IOException; +import java.io.InputStream; + +class SessionRetargetResponsePacket extends SessionServicePacket { + + private NbtAddress retargetAddress; + private int retargetPort; + + SessionRetargetResponsePacket() { + type = SESSION_RETARGET_RESPONSE; + length = 6; + } + + int writeTrailerWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readTrailerWireFormat( InputStream in, + byte[] buffer, + int bufferIndex ) + throws IOException { + if( in.read( buffer, bufferIndex, length ) != length ) { + throw new IOException( "unexpected EOF reading netbios retarget session response" ); + } + int addr = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + retargetAddress = new NbtAddress( null, addr, false, NbtAddress.B_NODE ); + retargetPort = readInt2( buffer, bufferIndex ); + return length; + } +} diff --git a/src/jcifs/netbios/SessionServicePacket.java b/src/jcifs/netbios/SessionServicePacket.java new file mode 100644 index 0000000..332e02e --- /dev/null +++ b/src/jcifs/netbios/SessionServicePacket.java @@ -0,0 +1,128 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.io.IOException; +import java.io.InputStream; + +public abstract class SessionServicePacket { + + // session service packet types + static final int SESSION_MESSAGE = 0x00; + static final int SESSION_REQUEST = 0x81; + public static final int POSITIVE_SESSION_RESPONSE = 0x82; + public static final int NEGATIVE_SESSION_RESPONSE = 0x83; + static final int SESSION_RETARGET_RESPONSE = 0x84; + static final int SESSION_KEEP_ALIVE = 0x85; + + static final int MAX_MESSAGE_SIZE = 0x0001FFFF; + static final int HEADER_LENGTH = 4; + + static void writeInt2( int val, byte[] dst, int dstIndex ) { + dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF ); + dst[dstIndex] = (byte)( val & 0xFF ); + } + static void writeInt4( int val, byte[] dst, int dstIndex ) { + dst[dstIndex++] = (byte)(( val >> 24 ) & 0xFF ); + dst[dstIndex++] = (byte)(( val >> 16 ) & 0xFF ); + dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF ); + dst[dstIndex] = (byte)( val & 0xFF ); + } + static int readInt2( byte[] src, int srcIndex ) { + return (( src[srcIndex] & 0xFF ) << 8 ) + + ( src[srcIndex + 1] & 0xFF ); + } + static int readInt4( byte[] src, int srcIndex ) { + return (( src[srcIndex] & 0xFF ) << 24 ) + + (( src[srcIndex + 1] & 0xFF ) << 16 ) + + (( src[srcIndex + 2] & 0xFF ) << 8 ) + + ( src[srcIndex + 3] & 0xFF ); + } + static int readLength( byte[] src, int srcIndex ) { + srcIndex++; + return (( src[srcIndex++] & 0x01 ) << 16 ) + + (( src[srcIndex++] & 0xFF ) << 8 ) + + ( src[srcIndex++] & 0xFF ); + } + static int readn( InputStream in, + byte[] b, + int off, + int len ) throws IOException { + int i = 0, n; + + while (i < len) { + n = in.read( b, off + i, len - i ); + if (n <= 0) { + break; + } + i += n; + } + + return i; + } + static int readPacketType( InputStream in, + byte[] buffer, + int bufferIndex ) + throws IOException { + int n; + if(( n = readn( in, buffer, bufferIndex, HEADER_LENGTH )) != HEADER_LENGTH ) { + if( n == -1 ) { + return -1; + } + throw new IOException( "unexpected EOF reading netbios session header" ); + } + int t = buffer[bufferIndex] & 0xFF; + return t; + } + + int type, length; + + public int writeWireFormat( byte[] dst, int dstIndex ) { + length = writeTrailerWireFormat( dst, dstIndex + HEADER_LENGTH ); + writeHeaderWireFormat( dst, dstIndex ); + return HEADER_LENGTH + length; + } + int readWireFormat( InputStream in, byte[] buffer, int bufferIndex ) throws IOException { + readHeaderWireFormat( in, buffer, bufferIndex ); + return HEADER_LENGTH + readTrailerWireFormat( in, buffer, bufferIndex ); + } + int writeHeaderWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = (byte)type; + if( length > 0x0000FFFF ) { + dst[dstIndex] = (byte)0x01; + } + dstIndex++; + writeInt2( length, dst, dstIndex ); + return HEADER_LENGTH; + } + int readHeaderWireFormat( InputStream in, + byte[] buffer, + int bufferIndex ) + throws IOException { + type = buffer[bufferIndex++] & 0xFF; + length = (( buffer[bufferIndex] & 0x01 ) << 16 ) + readInt2( buffer, bufferIndex + 1 ); + return HEADER_LENGTH; + } + + abstract int writeTrailerWireFormat( byte[] dst, int dstIndex ); + abstract int readTrailerWireFormat( InputStream in, + byte[] buffer, + int bufferIndex ) + throws IOException; +} diff --git a/src/jcifs/netbios/SocketInputStream.java b/src/jcifs/netbios/SocketInputStream.java new file mode 100644 index 0000000..f6ca644 --- /dev/null +++ b/src/jcifs/netbios/SocketInputStream.java @@ -0,0 +1,112 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.io.InputStream; +import java.io.IOException; + +class SocketInputStream extends InputStream { + + private static final int TMP_BUFFER_SIZE = 256; + + private InputStream in; + private SessionServicePacket ssp; + private int tot, bip, n; + private byte[] header, tmp; + + SocketInputStream( InputStream in ) { + this.in = in; + header = new byte[4]; + tmp = new byte[TMP_BUFFER_SIZE]; + } + + public synchronized int read() throws IOException { + if( read( tmp, 0, 1 ) < 0 ) { + return -1; + } + return tmp[0] & 0xFF; + } + public synchronized int read( byte[] b ) throws IOException { + return read( b, 0, b.length ); + } + + /* This method will not return until len bytes have been read + * or the stream has been closed. + */ + + public synchronized int read( byte[] b, int off, int len ) throws IOException { + if( len == 0 ) { + return 0; + } + tot = 0; + + while( true ) { + while( bip > 0 ) { + n = in.read( b, off, Math.min( len, bip )); + if( n == -1 ) { + return tot > 0 ? tot : -1; + } + tot += n; + off += n; + len -= n; + bip -= n; + if( len == 0 ) { + return tot; + } + } + + switch( SessionServicePacket.readPacketType( in, header, 0 )) { + case SessionServicePacket.SESSION_KEEP_ALIVE: + break; + case SessionServicePacket.SESSION_MESSAGE: + bip = SessionServicePacket.readLength( header, 0 ); + break; + case -1: + if( tot > 0 ) { + return tot; + } + return -1; + } + } + } + public synchronized long skip( long numbytes ) throws IOException { + if( numbytes <= 0 ) { + return 0; + } + long n = numbytes; + while( n > 0 ) { + int r = read( tmp, 0, (int)Math.min( (long)TMP_BUFFER_SIZE, n )); + if (r < 0) { + break; + } + n -= r; + } + return numbytes - n; + } + public int available() throws IOException { + if( bip > 0 ) { + return bip; + } + return in.available(); + } + public void close() throws IOException { + in.close(); + } +} + diff --git a/src/jcifs/netbios/SocketOutputStream.java b/src/jcifs/netbios/SocketOutputStream.java new file mode 100644 index 0000000..a2e9f83 --- /dev/null +++ b/src/jcifs/netbios/SocketOutputStream.java @@ -0,0 +1,47 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.netbios; + +import java.io.FilterOutputStream; +import java.io.OutputStream; +import java.io.IOException; + +class SocketOutputStream extends FilterOutputStream { + + SocketOutputStream( OutputStream out ) { + super( out ); + } + + public synchronized void write( byte[] b, int off, int len ) throws IOException { + if( len > 0xFFFF ) { + throw new IOException( "write too large: " + len ); + } else if( off < 4 ) { + throw new IOException( "NetBIOS socket output buffer requires 4 bytes available before off" ); + } + + off -= 4; + + b[off + 0] = (byte)SessionServicePacket.SESSION_MESSAGE; + b[off + 1] = (byte)0x00; + b[off + 2] = (byte)(( len >> 8 ) & 0xFF ); + b[off + 3] = (byte)( len & 0xFF ); + + out.write( b, off, 4 + len ); + } +} diff --git a/src/jcifs/ntlmssp/NtlmFlags.java b/src/jcifs/ntlmssp/NtlmFlags.java new file mode 100644 index 0000000..b7ae841 --- /dev/null +++ b/src/jcifs/ntlmssp/NtlmFlags.java @@ -0,0 +1,155 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.ntlmssp; + +/** + * Flags used during negotiation of NTLMSSP authentication. + */ +public interface NtlmFlags { + + /** + * Indicates whether Unicode strings are supported or used. + */ + public static final int NTLMSSP_NEGOTIATE_UNICODE = 0x00000001; + + /** + * Indicates whether OEM strings are supported or used. + */ + public static final int NTLMSSP_NEGOTIATE_OEM = 0x00000002; + + /** + * Indicates whether the authentication target is requested from + * the server. + */ + public static final int NTLMSSP_REQUEST_TARGET = 0x00000004; + + /** + * Specifies that communication across the authenticated channel + * should carry a digital signature (message integrity). + */ + public static final int NTLMSSP_NEGOTIATE_SIGN = 0x00000010; + + /** + * Specifies that communication across the authenticated channel + * should be encrypted (message confidentiality). + */ + public static final int NTLMSSP_NEGOTIATE_SEAL = 0x00000020; + + /** + * Indicates datagram authentication. + */ + public static final int NTLMSSP_NEGOTIATE_DATAGRAM_STYLE = 0x00000040; + + /** + * Indicates that the LAN Manager session key should be used for + * signing and sealing authenticated communication. + */ + public static final int NTLMSSP_NEGOTIATE_LM_KEY = 0x00000080; + + public static final int NTLMSSP_NEGOTIATE_NETWARE = 0x00000100; + + /** + * Indicates support for NTLM authentication. + */ + public static final int NTLMSSP_NEGOTIATE_NTLM = 0x00000200; + + /** + * Indicates whether the OEM-formatted domain name in which the + * client workstation has membership is supplied in the Type-1 message. + * This is used in the negotation of local authentication. + */ + public static final int NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED = + 0x00001000; + + /** + * Indicates whether the OEM-formatted workstation name is supplied + * in the Type-1 message. This is used in the negotiation of local + * authentication. + */ + public static final int NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED = + 0x00002000; + + /** + * Sent by the server to indicate that the server and client are + * on the same machine. This implies that the server will include + * a local security context handle in the Type 2 message, for + * use in local authentication. + */ + public static final int NTLMSSP_NEGOTIATE_LOCAL_CALL = 0x00004000; + + /** + * Indicates that authenticated communication between the client + * and server should carry a "dummy" digital signature. + */ + public static final int NTLMSSP_NEGOTIATE_ALWAYS_SIGN = 0x00008000; + + /** + * Sent by the server in the Type 2 message to indicate that the + * target authentication realm is a domain. + */ + public static final int NTLMSSP_TARGET_TYPE_DOMAIN = 0x00010000; + + /** + * Sent by the server in the Type 2 message to indicate that the + * target authentication realm is a server. + */ + public static final int NTLMSSP_TARGET_TYPE_SERVER = 0x00020000; + + /** + * Sent by the server in the Type 2 message to indicate that the + * target authentication realm is a share (presumably for share-level + * authentication). + */ + public static final int NTLMSSP_TARGET_TYPE_SHARE = 0x00040000; + + /** + * Indicates that the NTLM2 signing and sealing scheme should be used + * for protecting authenticated communications. This refers to a + * particular session security scheme, and is not related to the use + * of NTLMv2 authentication. + */ + public static final int NTLMSSP_NEGOTIATE_NTLM2 = 0x00080000; + + public static final int NTLMSSP_REQUEST_INIT_RESPONSE = 0x00100000; + + public static final int NTLMSSP_REQUEST_ACCEPT_RESPONSE = 0x00200000; + + public static final int NTLMSSP_REQUEST_NON_NT_SESSION_KEY = 0x00400000; + + /** + * Sent by the server in the Type 2 message to indicate that it is + * including a Target Information block in the message. The Target + * Information block is used in the calculation of the NTLMv2 response. + */ + public static final int NTLMSSP_NEGOTIATE_TARGET_INFO = 0x00800000; + + /** + * Indicates that 128-bit encryption is supported. + */ + public static final int NTLMSSP_NEGOTIATE_128 = 0x20000000; + + public static final int NTLMSSP_NEGOTIATE_KEY_EXCH = 0x40000000; + + /** + * Indicates that 56-bit encryption is supported. + */ + public static final int NTLMSSP_NEGOTIATE_56 = 0x80000000; + +} diff --git a/src/jcifs/ntlmssp/NtlmMessage.java b/src/jcifs/ntlmssp/NtlmMessage.java new file mode 100644 index 0000000..60ac21e --- /dev/null +++ b/src/jcifs/ntlmssp/NtlmMessage.java @@ -0,0 +1,136 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.ntlmssp; + +import jcifs.Config; + +/** + * Abstract superclass for all NTLMSSP messages. + */ +public abstract class NtlmMessage implements NtlmFlags { + + /** + * The NTLMSSP "preamble". + */ + protected static final byte[] NTLMSSP_SIGNATURE = new byte[] { + (byte) 'N', (byte) 'T', (byte) 'L', (byte) 'M', + (byte) 'S', (byte) 'S', (byte) 'P', (byte) 0 + }; + + private static final String OEM_ENCODING = Config.DEFAULT_OEM_ENCODING; + protected static final String UNI_ENCODING = "UTF-16LE"; + + private int flags; + + /** + * Returns the flags currently in use for this message. + * + * @return An int containing the flags in use for this + * message. + */ + public int getFlags() { + return flags; + } + + /** + * Sets the flags for this message. + * + * @param flags The flags for this message. + */ + public void setFlags(int flags) { + this.flags = flags; + } + + /** + * Returns the status of the specified flag. + * + * @param flag The flag to test (i.e., NTLMSSP_NEGOTIATE_OEM). + * @return A boolean indicating whether the flag is set. + */ + public boolean getFlag(int flag) { + return (getFlags() & flag) != 0; + } + + /** + * Sets or clears the specified flag. + * + * @param flag The flag to set/clear (i.e., + * NTLMSSP_NEGOTIATE_OEM). + * @param value Indicates whether to set (true) or + * clear (false) the specified flag. + */ + public void setFlag(int flag, boolean value) { + setFlags(value ? (getFlags() | flag) : + (getFlags() & (0xffffffff ^ flag))); + } + + static int readULong(byte[] src, int index) { + return (src[index] & 0xff) | + ((src[index + 1] & 0xff) << 8) | + ((src[index + 2] & 0xff) << 16) | + ((src[index + 3] & 0xff) << 24); + } + + static int readUShort(byte[] src, int index) { + return (src[index] & 0xff) | ((src[index + 1] & 0xff) << 8); + } + + static byte[] readSecurityBuffer(byte[] src, int index) { + int length = readUShort(src, index); + int offset = readULong(src, index + 4); + byte[] buffer = new byte[length]; + System.arraycopy(src, offset, buffer, 0, length); + return buffer; + } + + static void writeULong(byte[] dest, int offset, int ulong) { + dest[offset] = (byte) (ulong & 0xff); + dest[offset + 1] = (byte) (ulong >> 8 & 0xff); + dest[offset + 2] = (byte) (ulong >> 16 & 0xff); + dest[offset + 3] = (byte) (ulong >> 24 & 0xff); + } + + static void writeUShort(byte[] dest, int offset, int ushort) { + dest[offset] = (byte) (ushort & 0xff); + dest[offset + 1] = (byte) (ushort >> 8 & 0xff); + } + + static void writeSecurityBuffer(byte[] dest, int offset, int bodyOffset, + byte[] src) { + int length = (src != null) ? src.length : 0; + if (length == 0) return; + writeUShort(dest, offset, length); + writeUShort(dest, offset + 2, length); + writeULong(dest, offset + 4, bodyOffset); + System.arraycopy(src, 0, dest, bodyOffset, length); + } + + static String getOEMEncoding() { + return OEM_ENCODING; + } + + /** + * Returns the raw byte representation of this message. + * + * @return A byte[] containing the raw message material. + */ + public abstract byte[] toByteArray(); + +} diff --git a/src/jcifs/ntlmssp/Type1Message.java b/src/jcifs/ntlmssp/Type1Message.java new file mode 100644 index 0000000..c4d1c3c --- /dev/null +++ b/src/jcifs/ntlmssp/Type1Message.java @@ -0,0 +1,230 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.ntlmssp; + +import java.io.IOException; + +import java.net.UnknownHostException; + +import jcifs.netbios.NbtAddress; + +import jcifs.Config; + +/** + * Represents an NTLMSSP Type-1 message. + */ +public class Type1Message extends NtlmMessage { + + private static final int DEFAULT_FLAGS; + + private static final String DEFAULT_DOMAIN; + + private static final String DEFAULT_WORKSTATION; + + private String suppliedDomain; + + private String suppliedWorkstation; + + static { + DEFAULT_FLAGS = NTLMSSP_NEGOTIATE_NTLM | + (Config.getBoolean("jcifs.smb.client.useUnicode", true) ? + NTLMSSP_NEGOTIATE_UNICODE : NTLMSSP_NEGOTIATE_OEM); + DEFAULT_DOMAIN = Config.getProperty("jcifs.smb.client.domain", null); + String defaultWorkstation = null; + try { + defaultWorkstation = NbtAddress.getLocalHost().getHostName(); + } catch (UnknownHostException ex) { } + DEFAULT_WORKSTATION = defaultWorkstation; + } + + /** + * Creates a Type-1 message using default values from the current + * environment. + */ + public Type1Message() { + this(getDefaultFlags(), getDefaultDomain(), getDefaultWorkstation()); + } + + /** + * Creates a Type-1 message with the specified parameters. + * + * @param flags The flags to apply to this message. + * @param suppliedDomain The supplied authentication domain. + * @param suppliedWorkstation The supplied workstation name. + */ + public Type1Message(int flags, String suppliedDomain, + String suppliedWorkstation) { + setFlags(getDefaultFlags() | flags); + setSuppliedDomain(suppliedDomain); + if (suppliedWorkstation == null) + suppliedWorkstation = getDefaultWorkstation(); + setSuppliedWorkstation(suppliedWorkstation); + } + + /** + * Creates a Type-1 message using the given raw Type-1 material. + * + * @param material The raw Type-1 material used to construct this message. + * @throws IOException If an error occurs while parsing the material. + */ + public Type1Message(byte[] material) throws IOException { + parse(material); + } + + /** + * Returns the supplied authentication domain. + * + * @return A String containing the supplied domain. + */ + public String getSuppliedDomain() { + return suppliedDomain; + } + + /** + * Sets the supplied authentication domain for this message. + * + * @param suppliedDomain The supplied domain for this message. + */ + public void setSuppliedDomain(String suppliedDomain) { + this.suppliedDomain = suppliedDomain; + } + + /** + * Returns the supplied workstation name. + * + * @return A String containing the supplied workstation name. + */ + public String getSuppliedWorkstation() { + return suppliedWorkstation; + } + + /** + * Sets the supplied workstation name for this message. + * + * @param suppliedWorkstation The supplied workstation for this message. + */ + public void setSuppliedWorkstation(String suppliedWorkstation) { + this.suppliedWorkstation = suppliedWorkstation; + } + + public byte[] toByteArray() { + try { + String suppliedDomain = getSuppliedDomain(); + String suppliedWorkstation = getSuppliedWorkstation(); + int flags = getFlags(); + boolean hostInfo = false; + byte[] domain = new byte[0]; + if (suppliedDomain != null && suppliedDomain.length() != 0) { + hostInfo = true; + flags |= NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED; + domain = suppliedDomain.toUpperCase().getBytes( + getOEMEncoding()); + } else { + flags &= (NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED ^ 0xffffffff); + } + byte[] workstation = new byte[0]; + if (suppliedWorkstation != null && + suppliedWorkstation.length() != 0) { + hostInfo = true; + flags |= NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED; + workstation = + suppliedWorkstation.toUpperCase().getBytes( + getOEMEncoding()); + } else { + flags &= (NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED ^ + 0xffffffff); + } + byte[] type1 = new byte[hostInfo ? + (32 + domain.length + workstation.length) : 16]; + System.arraycopy(NTLMSSP_SIGNATURE, 0, type1, 0, 8); + writeULong(type1, 8, 1); + writeULong(type1, 12, flags); + if (hostInfo) { + writeSecurityBuffer(type1, 16, 32, domain); + writeSecurityBuffer(type1, 24, 32 + domain.length, workstation); + } + return type1; + } catch (IOException ex) { + throw new IllegalStateException(ex.getMessage()); + } + } + + public String toString() { + String suppliedDomain = getSuppliedDomain(); + String suppliedWorkstation = getSuppliedWorkstation(); + return "Type1Message[suppliedDomain=" + (suppliedDomain == null ? "null" : suppliedDomain) + + ",suppliedWorkstation=" + (suppliedWorkstation == null ? "null" : suppliedWorkstation) + + ",flags=0x" + jcifs.util.Hexdump.toHexString(getFlags(), 8) + "]"; + } + + /** + * Returns the default flags for a generic Type-1 message in the + * current environment. + * + * @return An int containing the default flags. + */ + public static int getDefaultFlags() { + return DEFAULT_FLAGS; + } + + /** + * Returns the default domain from the current environment. + * + * @return A String containing the default domain. + */ + public static String getDefaultDomain() { + return DEFAULT_DOMAIN; + } + + /** + * Returns the default workstation from the current environment. + * + * @return A String containing the default workstation. + */ + public static String getDefaultWorkstation() { + return DEFAULT_WORKSTATION; + } + + private void parse(byte[] material) throws IOException { + for (int i = 0; i < 8; i++) { + if (material[i] != NTLMSSP_SIGNATURE[i]) { + throw new IOException("Not an NTLMSSP message."); + } + } + if (readULong(material, 8) != 1) { + throw new IOException("Not a Type 1 message."); + } + int flags = readULong(material, 12); + String suppliedDomain = null; + if ((flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) != 0) { + byte[] domain = readSecurityBuffer(material, 16); + suppliedDomain = new String(domain, getOEMEncoding()); + } + String suppliedWorkstation = null; + if ((flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) != 0) { + byte[] workstation = readSecurityBuffer(material, 24); + suppliedWorkstation = new String(workstation, getOEMEncoding()); + } + setFlags(flags); + setSuppliedDomain(suppliedDomain); + setSuppliedWorkstation(suppliedWorkstation); + } + +} diff --git a/src/jcifs/ntlmssp/Type2Message.java b/src/jcifs/ntlmssp/Type2Message.java new file mode 100644 index 0000000..a8f9e3d --- /dev/null +++ b/src/jcifs/ntlmssp/Type2Message.java @@ -0,0 +1,373 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.ntlmssp; + +import java.io.IOException; + +import java.net.UnknownHostException; + +import jcifs.Config; + +import jcifs.netbios.NbtAddress; + +/** + * Represents an NTLMSSP Type-2 message. + */ +public class Type2Message extends NtlmMessage { + + private static final int DEFAULT_FLAGS; + + private static final String DEFAULT_DOMAIN; + + private static final byte[] DEFAULT_TARGET_INFORMATION; + + private byte[] challenge; + + private String target; + + private byte[] context; + + private byte[] targetInformation; + + static { + DEFAULT_FLAGS = NTLMSSP_NEGOTIATE_NTLM | + (Config.getBoolean("jcifs.smb.client.useUnicode", true) ? + NTLMSSP_NEGOTIATE_UNICODE : NTLMSSP_NEGOTIATE_OEM); + DEFAULT_DOMAIN = Config.getProperty("jcifs.smb.client.domain", null); + byte[] domain = new byte[0]; + if (DEFAULT_DOMAIN != null) { + try { + domain = DEFAULT_DOMAIN.getBytes(UNI_ENCODING); + } catch (IOException ex) { } + } + int domainLength = domain.length; + byte[] server = new byte[0]; + try { + String host = NbtAddress.getLocalHost().getHostName(); + if (host != null) { + try { + server = host.getBytes(UNI_ENCODING); + } catch (IOException ex) { } + } + } catch (UnknownHostException ex) { } + int serverLength = server.length; + byte[] targetInfo = new byte[(domainLength > 0 ? domainLength + 4 : 0) + + (serverLength > 0 ? serverLength + 4 : 0) + 4]; + int offset = 0; + if (domainLength > 0) { + writeUShort(targetInfo, offset, 2); + offset += 2; + writeUShort(targetInfo, offset, domainLength); + offset += 2; + System.arraycopy(domain, 0, targetInfo, offset, domainLength); + offset += domainLength; + } + if (serverLength > 0) { + writeUShort(targetInfo, offset, 1); + offset += 2; + writeUShort(targetInfo, offset, serverLength); + offset += 2; + System.arraycopy(server, 0, targetInfo, offset, serverLength); + } + DEFAULT_TARGET_INFORMATION = targetInfo; + } + + /** + * Creates a Type-2 message using default values from the current + * environment. + */ + public Type2Message() { + this(getDefaultFlags(), null, null); + } + + /** + * Creates a Type-2 message in response to the given Type-1 message + * using default values from the current environment. + * + * @param type1 The Type-1 message which this represents a response to. + */ + public Type2Message(Type1Message type1) { + this(type1, null, null); + } + + /** + * Creates a Type-2 message in response to the given Type-1 message. + * + * @param type1 The Type-1 message which this represents a response to. + * @param challenge The challenge from the domain controller/server. + * @param target The authentication target. + */ + public Type2Message(Type1Message type1, byte[] challenge, String target) { + this(getDefaultFlags(type1), challenge, (type1 != null && + target == null && type1.getFlag(NTLMSSP_REQUEST_TARGET)) ? + getDefaultDomain() : target); + } + + /** + * Creates a Type-2 message with the specified parameters. + * + * @param flags The flags to apply to this message. + * @param challenge The challenge from the domain controller/server. + * @param target The authentication target. + */ + public Type2Message(int flags, byte[] challenge, String target) { + setFlags(flags); + setChallenge(challenge); + setTarget(target); + if (target != null) setTargetInformation(getDefaultTargetInformation()); + } + + /** + * Creates a Type-2 message using the given raw Type-2 material. + * + * @param material The raw Type-2 material used to construct this message. + * @throws IOException If an error occurs while parsing the material. + */ + public Type2Message(byte[] material) throws IOException { + parse(material); + } + + /** + * Returns the challenge for this message. + * + * @return A byte[] containing the challenge. + */ + public byte[] getChallenge() { + return challenge; + } + + /** + * Sets the challenge for this message. + * + * @param challenge The challenge from the domain controller/server. + */ + public void setChallenge(byte[] challenge) { + this.challenge = challenge; + } + + /** + * Returns the authentication target. + * + * @return A String containing the authentication target. + */ + public String getTarget() { + return target; + } + + /** + * Sets the authentication target. + * + * @param target The authentication target. + */ + public void setTarget(String target) { + this.target = target; + } + + /** + * Returns the target information block. + * + * @return A byte[] containing the target information block. + * The target information block is used by the client to create an + * NTLMv2 response. + */ + public byte[] getTargetInformation() { + return targetInformation; + } + + /** + * Sets the target information block. + * The target information block is used by the client to create + * an NTLMv2 response. + * + * @param targetInformation The target information block. + */ + public void setTargetInformation(byte[] targetInformation) { + this.targetInformation = targetInformation; + } + + /** + * Returns the local security context. + * + * @return A byte[] containing the local security + * context. This is used by the client to negotiate local + * authentication. + */ + public byte[] getContext() { + return context; + } + + /** + * Sets the local security context. This is used by the client + * to negotiate local authentication. + * + * @param context The local security context. + */ + public void setContext(byte[] context) { + this.context = context; + } + + public byte[] toByteArray() { + try { + String targetName = getTarget(); + byte[] challenge = getChallenge(); + byte[] context = getContext(); + byte[] targetInformation = getTargetInformation(); + int flags = getFlags(); + byte[] target = new byte[0]; + if ((flags & (NTLMSSP_TARGET_TYPE_DOMAIN | + NTLMSSP_TARGET_TYPE_SERVER | + NTLMSSP_TARGET_TYPE_SHARE)) != 0) { + if (targetName != null && targetName.length() != 0) { + target = (flags & NTLMSSP_NEGOTIATE_UNICODE) != 0 ? + targetName.getBytes(UNI_ENCODING) : + targetName.toUpperCase().getBytes(getOEMEncoding()); + } else { + flags &= (0xffffffff ^ (NTLMSSP_TARGET_TYPE_DOMAIN | + NTLMSSP_TARGET_TYPE_SERVER | + NTLMSSP_TARGET_TYPE_SHARE)); + } + } + if (targetInformation != null) { + flags |= NTLMSSP_NEGOTIATE_TARGET_INFO; + // empty context is needed for padding when t.i. is supplied. + if (context == null) context = new byte[8]; + } + int data = 32; + if (context != null) data += 8; + if (targetInformation != null) data += 8; + byte[] type2 = new byte[data + target.length + + (targetInformation != null ? targetInformation.length : 0)]; + System.arraycopy(NTLMSSP_SIGNATURE, 0, type2, 0, 8); + writeULong(type2, 8, 2); + writeSecurityBuffer(type2, 12, data, target); + writeULong(type2, 20, flags); + System.arraycopy(challenge != null ? challenge : new byte[8], 0, + type2, 24, 8); + if (context != null) System.arraycopy(context, 0, type2, 32, 8); + if (targetInformation != null) { + writeSecurityBuffer(type2, 40, data + target.length, + targetInformation); + } + return type2; + } catch (IOException ex) { + throw new IllegalStateException(ex.getMessage()); + } + } + + public String toString() { + String target = getTarget(); + byte[] challenge = getChallenge(); + byte[] context = getContext(); + byte[] targetInformation = getTargetInformation(); + + return "Type2Message[target=" + target + + ",challenge=" + (challenge == null ? "null" : "<" + challenge.length + " bytes>") + + ",context=" + (context == null ? "null" : "<" + context.length + " bytes>") + + ",targetInformation=" + (targetInformation == null ? "null" : "<" + targetInformation.length + " bytes>") + + ",flags=0x" + jcifs.util.Hexdump.toHexString(getFlags(), 8) + "]"; + } + + /** + * Returns the default flags for a generic Type-2 message in the + * current environment. + * + * @return An int containing the default flags. + */ + public static int getDefaultFlags() { + return DEFAULT_FLAGS; + } + + /** + * Returns the default flags for a Type-2 message created in response + * to the given Type-1 message in the current environment. + * + * @return An int containing the default flags. + */ + public static int getDefaultFlags(Type1Message type1) { + if (type1 == null) return DEFAULT_FLAGS; + int flags = NTLMSSP_NEGOTIATE_NTLM; + int type1Flags = type1.getFlags(); + flags |= ((type1Flags & NTLMSSP_NEGOTIATE_UNICODE) != 0) ? + NTLMSSP_NEGOTIATE_UNICODE : NTLMSSP_NEGOTIATE_OEM; + if ((type1Flags & NTLMSSP_REQUEST_TARGET) != 0) { + String domain = getDefaultDomain(); + if (domain != null) { + flags |= NTLMSSP_REQUEST_TARGET | NTLMSSP_TARGET_TYPE_DOMAIN; + } + } + return flags; + } + + /** + * Returns the default domain from the current environment. + * + * @return A String containing the domain. + */ + public static String getDefaultDomain() { + return DEFAULT_DOMAIN; + } + + public static byte[] getDefaultTargetInformation() { + return DEFAULT_TARGET_INFORMATION; + } + + private void parse(byte[] material) throws IOException { + for (int i = 0; i < 8; i++) { + if (material[i] != NTLMSSP_SIGNATURE[i]) { + throw new IOException("Not an NTLMSSP message."); + } + } + if (readULong(material, 8) != 2) { + throw new IOException("Not a Type 2 message."); + } + int flags = readULong(material, 20); + setFlags(flags); + String target = null; + byte[] bytes = readSecurityBuffer(material, 12); + if (bytes.length != 0) { + target = new String(bytes, + ((flags & NTLMSSP_NEGOTIATE_UNICODE) != 0) ? + UNI_ENCODING : getOEMEncoding()); + } + setTarget(target); + for (int i = 24; i < 32; i++) { + if (material[i] != 0) { + byte[] challenge = new byte[8]; + System.arraycopy(material, 24, challenge, 0, 8); + setChallenge(challenge); + break; + } + } + int offset = readULong(material, 16); // offset of targetname start + if (offset == 32 || material.length == 32) return; + for (int i = 32; i < 40; i++) { + if (material[i] != 0) { + byte[] context = new byte[8]; + System.arraycopy(material, 32, context, 0, 8); + setContext(context); + break; + } + } + if (offset == 40 || material.length == 40) return; + bytes = readSecurityBuffer(material, 40); + if (bytes.length != 0) setTargetInformation(bytes); + } + +} diff --git a/src/jcifs/ntlmssp/Type3Message.java b/src/jcifs/ntlmssp/Type3Message.java new file mode 100644 index 0000000..9db625a --- /dev/null +++ b/src/jcifs/ntlmssp/Type3Message.java @@ -0,0 +1,655 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.ntlmssp; + +import java.io.IOException; + +import java.net.UnknownHostException; + +import java.security.SecureRandom; + +import jcifs.Config; + +import jcifs.netbios.NbtAddress; + +import jcifs.smb.NtlmPasswordAuthentication; +import jcifs.util.HMACT64; +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import java.security.GeneralSecurityException; +import jcifs.util.MD4; +import jcifs.util.RC4; + +/** + * Represents an NTLMSSP Type-3 message. + */ +public class Type3Message extends NtlmMessage { + + static final long MILLISECONDS_BETWEEN_1970_AND_1601 = 11644473600000L; + + private static final int DEFAULT_FLAGS; + + private static final String DEFAULT_DOMAIN; + + private static final String DEFAULT_USER; + + private static final String DEFAULT_PASSWORD; + + private static final String DEFAULT_WORKSTATION; + + private static final int LM_COMPATIBILITY; + + private static final SecureRandom RANDOM = new SecureRandom(); + + private byte[] lmResponse; + + private byte[] ntResponse; + + private String domain; + + private String user; + + private String workstation; + + private byte[] masterKey = null; + private byte[] sessionKey = null; + + static { + DEFAULT_FLAGS = NTLMSSP_NEGOTIATE_NTLM | + (Config.getBoolean("jcifs.smb.client.useUnicode", true) ? + NTLMSSP_NEGOTIATE_UNICODE : NTLMSSP_NEGOTIATE_OEM); + DEFAULT_DOMAIN = Config.getProperty("jcifs.smb.client.domain", null); + DEFAULT_USER = Config.getProperty("jcifs.smb.client.username", null); + DEFAULT_PASSWORD = Config.getProperty("jcifs.smb.client.password", + null); + String defaultWorkstation = null; + try { + defaultWorkstation = NbtAddress.getLocalHost().getHostName(); + } catch (UnknownHostException ex) { } + DEFAULT_WORKSTATION = defaultWorkstation; + LM_COMPATIBILITY = Config.getInt("jcifs.smb.lmCompatibility", 3); + } + + /** + * Creates a Type-3 message using default values from the current + * environment. + */ + public Type3Message() { + setFlags(getDefaultFlags()); + setDomain(getDefaultDomain()); + setUser(getDefaultUser()); + setWorkstation(getDefaultWorkstation()); + } + + /** + * Creates a Type-3 message in response to the given Type-2 message + * using default values from the current environment. + * + * @param type2 The Type-2 message which this represents a response to. + */ + public Type3Message(Type2Message type2) { + setFlags(getDefaultFlags(type2)); + setWorkstation(getDefaultWorkstation()); + String domain = getDefaultDomain(); + setDomain(domain); + String user = getDefaultUser(); + setUser(user); + String password = getDefaultPassword(); + switch (LM_COMPATIBILITY) { + case 0: + case 1: + setLMResponse(getLMResponse(type2, password)); + setNTResponse(getNTResponse(type2, password)); + break; + case 2: + byte[] nt = getNTResponse(type2, password); + setLMResponse(nt); + setNTResponse(nt); + break; + case 3: + case 4: + case 5: + byte[] clientChallenge = new byte[8]; + RANDOM.nextBytes(clientChallenge); + setLMResponse(getLMv2Response(type2, domain, user, password, + clientChallenge)); + /* + setNTResponse(getNTLMv2Response(type2, domain, user, password, + clientChallenge)); + */ + break; + default: + setLMResponse(getLMResponse(type2, password)); + setNTResponse(getNTResponse(type2, password)); + } + } + + /** + * Creates a Type-3 message in response to the given Type-2 message. + * + * @param type2 The Type-2 message which this represents a response to. + * @param password The password to use when constructing the response. + * @param domain The domain in which the user has an account. + * @param user The username for the authenticating user. + * @param workstation The workstation from which authentication is + * taking place. + */ + public Type3Message(Type2Message type2, String password, String domain, + String user, String workstation, int flags) { + setFlags(flags | getDefaultFlags(type2)); + if (workstation == null) + workstation = getDefaultWorkstation(); + setWorkstation(workstation); + setDomain(domain); + setUser(user); + + switch (LM_COMPATIBILITY) { + case 0: + case 1: + if ((getFlags() & NTLMSSP_NEGOTIATE_NTLM2) == 0) { + setLMResponse(getLMResponse(type2, password)); + setNTResponse(getNTResponse(type2, password)); + } else { + // NTLM2 Session Response + + byte[] clientChallenge = new byte[24]; + RANDOM.nextBytes(clientChallenge); + java.util.Arrays.fill(clientChallenge, 8, 24, (byte)0x00); + +// NTLMv1 w/ NTLM2 session sec and key exch all been verified with a debug build of smbclient + + byte[] responseKeyNT = NtlmPasswordAuthentication.nTOWFv1(password); + byte[] ntlm2Response = NtlmPasswordAuthentication.getNTLM2Response(responseKeyNT, + type2.getChallenge(), + clientChallenge); + + setLMResponse(clientChallenge); + setNTResponse(ntlm2Response); + + if ((getFlags() & NTLMSSP_NEGOTIATE_SIGN) == NTLMSSP_NEGOTIATE_SIGN) { + byte[] sessionNonce = new byte[16]; + System.arraycopy(type2.getChallenge(), 0, sessionNonce, 0, 8); + System.arraycopy(clientChallenge, 0, sessionNonce, 8, 8); + + MD4 md4 = new MD4(); + md4.update(responseKeyNT); + byte[] userSessionKey = md4.digest(); + + HMACT64 hmac = new HMACT64(userSessionKey); + hmac.update(sessionNonce); + byte[] ntlm2SessionKey = hmac.digest(); + + if ((getFlags() & NTLMSSP_NEGOTIATE_KEY_EXCH) != 0) { + masterKey = new byte[16]; + RANDOM.nextBytes(masterKey); + + byte[] exchangedKey = new byte[16]; + RC4 rc4 = new RC4(ntlm2SessionKey); + rc4.update(masterKey, 0, 16, exchangedKey, 0); +/* RC4 was not added to Java until 1.5u7 so let's use our own for a little while longer ... + try { + Cipher rc4 = Cipher.getInstance("RC4"); + rc4.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(ntlm2SessionKey, "RC4")); + rc4.update(masterKey, 0, 16, exchangedKey, 0); + } catch (GeneralSecurityException gse) { + throw new RuntimeException("", gse); + } +*/ + + setSessionKey(exchangedKey); + } else { + masterKey = ntlm2SessionKey; + setSessionKey(masterKey); + } + } + } + break; + case 2: + byte[] nt = getNTResponse(type2, password); + setLMResponse(nt); + setNTResponse(nt); + break; + case 3: + case 4: + case 5: + byte[] responseKeyNT = NtlmPasswordAuthentication.nTOWFv2(domain, user, password); + + byte[] clientChallenge = new byte[8]; + RANDOM.nextBytes(clientChallenge); + setLMResponse(getLMv2Response(type2, domain, user, password, clientChallenge)); + + byte[] clientChallenge2 = new byte[8]; + RANDOM.nextBytes(clientChallenge2); + setNTResponse(getNTLMv2Response(type2, responseKeyNT, clientChallenge2)); + + if ((getFlags() & NTLMSSP_NEGOTIATE_SIGN) == NTLMSSP_NEGOTIATE_SIGN) { + HMACT64 hmac = new HMACT64(responseKeyNT); + hmac.update(ntResponse, 0, 16); // only first 16 bytes of ntResponse + byte[] userSessionKey = hmac.digest(); + + if ((getFlags() & NTLMSSP_NEGOTIATE_KEY_EXCH) != 0) { + masterKey = new byte[16]; + RANDOM.nextBytes(masterKey); + + byte[] exchangedKey = new byte[16]; + RC4 rc4 = new RC4(userSessionKey); + rc4.update(masterKey, 0, 16, exchangedKey, 0); +/* RC4 was not added to Java until 1.5u7 so let's use our own for a little while longer ... + try { + Cipher rc4 = Cipher.getInstance("RC4"); + rc4.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(userSessionKey, "RC4")); + rc4.update(masterKey, 0, 16, exchangedKey, 0); + } catch (GeneralSecurityException gse) { + throw new RuntimeException("", gse); + } +*/ + + setSessionKey(exchangedKey); + } else { + masterKey = userSessionKey; + setSessionKey(masterKey); + } + } + + break; + default: + setLMResponse(getLMResponse(type2, password)); + setNTResponse(getNTResponse(type2, password)); + } + } + + /** + * Creates a Type-3 message with the specified parameters. + * + * @param flags The flags to apply to this message. + * @param lmResponse The LanManager/LMv2 response. + * @param ntResponse The NT/NTLMv2 response. + * @param domain The domain in which the user has an account. + * @param user The username for the authenticating user. + * @param workstation The workstation from which authentication is + * taking place. + */ + public Type3Message(int flags, byte[] lmResponse, byte[] ntResponse, + String domain, String user, String workstation) { + setFlags(flags); + setLMResponse(lmResponse); + setNTResponse(ntResponse); + setDomain(domain); + setUser(user); + setWorkstation(workstation); + } + + /** + * Creates a Type-3 message using the given raw Type-3 material. + * + * @param material The raw Type-3 material used to construct this message. + * @throws IOException If an error occurs while parsing the material. + */ + public Type3Message(byte[] material) throws IOException { + parse(material); + } + + /** + * Returns the LanManager/LMv2 response. + * + * @return A byte[] containing the LanManager response. + */ + public byte[] getLMResponse() { + return lmResponse; + } + + /** + * Sets the LanManager/LMv2 response for this message. + * + * @param lmResponse The LanManager response. + */ + public void setLMResponse(byte[] lmResponse) { + this.lmResponse = lmResponse; + } + + /** + * Returns the NT/NTLMv2 response. + * + * @return A byte[] containing the NT/NTLMv2 response. + */ + public byte[] getNTResponse() { + return ntResponse; + } + + /** + * Sets the NT/NTLMv2 response for this message. + * + * @param ntResponse The NT/NTLMv2 response. + */ + public void setNTResponse(byte[] ntResponse) { + this.ntResponse = ntResponse; + } + + /** + * Returns the domain in which the user has an account. + * + * @return A String containing the domain for the user. + */ + public String getDomain() { + return domain; + } + + /** + * Sets the domain for this message. + * + * @param domain The domain. + */ + public void setDomain(String domain) { + this.domain = domain; + } + + /** + * Returns the username for the authenticating user. + * + * @return A String containing the user for this message. + */ + public String getUser() { + return user; + } + + /** + * Sets the user for this message. + * + * @param user The user. + */ + public void setUser(String user) { + this.user = user; + } + + /** + * Returns the workstation from which authentication is being performed. + * + * @return A String containing the workstation. + */ + public String getWorkstation() { + return workstation; + } + + /** + * Sets the workstation for this message. + * + * @param workstation The workstation. + */ + public void setWorkstation(String workstation) { + this.workstation = workstation; + } + + /** + * The real session key if the regular session key is actually + * the encrypted version used for key exchange. + * + * @return A byte[] containing the session key. + */ + public byte[] getMasterKey() { + return masterKey; + } + + /** + * Returns the session key. + * + * @return A byte[] containing the session key. + */ + public byte[] getSessionKey() { + return sessionKey; + } + + /** + * Sets the session key. + * + * @param sessionKey The session key. + */ + public void setSessionKey(byte[] sessionKey) { + this.sessionKey = sessionKey; + } + + public byte[] toByteArray() { + try { + int flags = getFlags(); + boolean unicode = (flags & NTLMSSP_NEGOTIATE_UNICODE) != 0; + String oem = unicode ? null : getOEMEncoding(); + String domainName = getDomain(); + byte[] domain = null; + if (domainName != null && domainName.length() != 0) { + domain = unicode ? + domainName.getBytes(UNI_ENCODING) : + domainName.getBytes(oem); + } + int domainLength = (domain != null) ? domain.length : 0; + String userName = getUser(); + byte[] user = null; + if (userName != null && userName.length() != 0) { + user = unicode ? userName.getBytes(UNI_ENCODING) : + userName.toUpperCase().getBytes(oem); + } + int userLength = (user != null) ? user.length : 0; + String workstationName = getWorkstation(); + byte[] workstation = null; + if (workstationName != null && workstationName.length() != 0) { + workstation = unicode ? + workstationName.getBytes(UNI_ENCODING) : + workstationName.toUpperCase().getBytes(oem); + } + int workstationLength = (workstation != null) ? + workstation.length : 0; + byte[] lmResponse = getLMResponse(); + int lmLength = (lmResponse != null) ? lmResponse.length : 0; + byte[] ntResponse = getNTResponse(); + int ntLength = (ntResponse != null) ? ntResponse.length : 0; + byte[] sessionKey = getSessionKey(); + int keyLength = (sessionKey != null) ? sessionKey.length : 0; + byte[] type3 = new byte[64 + domainLength + userLength + + workstationLength + lmLength + ntLength + keyLength]; + System.arraycopy(NTLMSSP_SIGNATURE, 0, type3, 0, 8); + writeULong(type3, 8, 3); + int offset = 64; + writeSecurityBuffer(type3, 12, offset, lmResponse); + offset += lmLength; + writeSecurityBuffer(type3, 20, offset, ntResponse); + offset += ntLength; + writeSecurityBuffer(type3, 28, offset, domain); + offset += domainLength; + writeSecurityBuffer(type3, 36, offset, user); + offset += userLength; + writeSecurityBuffer(type3, 44, offset, workstation); + offset += workstationLength; + writeSecurityBuffer(type3, 52, offset, sessionKey); + writeULong(type3, 60, flags); + return type3; + } catch (IOException ex) { + throw new IllegalStateException(ex.getMessage()); + } + } + + public String toString() { + String user = getUser(); + String domain = getDomain(); + String workstation = getWorkstation(); + byte[] lmResponse = getLMResponse(); + byte[] ntResponse = getNTResponse(); + byte[] sessionKey = getSessionKey(); + + return "Type3Message[domain=" + domain + + ",user=" + user + + ",workstation=" + workstation + + ",lmResponse=" + (lmResponse == null ? "null" : "<" + lmResponse.length + " bytes>") + + ",ntResponse=" + (ntResponse == null ? "null" : "<" + ntResponse.length + " bytes>") + + ",sessionKey=" + (sessionKey == null ? "null" : "<" + sessionKey.length + " bytes>") + + ",flags=0x" + jcifs.util.Hexdump.toHexString(getFlags(), 8) + "]"; + } + + /** + * Returns the default flags for a generic Type-3 message in the + * current environment. + * + * @return An int containing the default flags. + */ + public static int getDefaultFlags() { + return DEFAULT_FLAGS; + } + + /** + * Returns the default flags for a Type-3 message created in response + * to the given Type-2 message in the current environment. + * + * @return An int containing the default flags. + */ + public static int getDefaultFlags(Type2Message type2) { + if (type2 == null) return DEFAULT_FLAGS; + int flags = NTLMSSP_NEGOTIATE_NTLM; + flags |= ((type2.getFlags() & NTLMSSP_NEGOTIATE_UNICODE) != 0) ? + NTLMSSP_NEGOTIATE_UNICODE : NTLMSSP_NEGOTIATE_OEM; + return flags; + } + + /** + * Constructs the LanManager response to the given Type-2 message using + * the supplied password. + * + * @param type2 The Type-2 message. + * @param password The password. + * @return A byte[] containing the LanManager response. + */ + public static byte[] getLMResponse(Type2Message type2, String password) { + if (type2 == null || password == null) return null; + return NtlmPasswordAuthentication.getPreNTLMResponse(password, + type2.getChallenge()); + } + + public static byte[] getLMv2Response(Type2Message type2, + String domain, String user, String password, + byte[] clientChallenge) { + if (type2 == null || domain == null || user == null || + password == null || clientChallenge == null) { + return null; + } + return NtlmPasswordAuthentication.getLMv2Response(domain, user, + password, type2.getChallenge(), clientChallenge); + } + public static byte[] getNTLMv2Response(Type2Message type2, + byte[] responseKeyNT, + byte[] clientChallenge) { + if (type2 == null || responseKeyNT == null || clientChallenge == null) { + return null; + } + long nanos1601 = (System.currentTimeMillis() + MILLISECONDS_BETWEEN_1970_AND_1601) * 10000L; + return NtlmPasswordAuthentication.getNTLMv2Response(responseKeyNT, + type2.getChallenge(), + clientChallenge, + nanos1601, + type2.getTargetInformation()); + } + + /** + * Constructs the NT response to the given Type-2 message using + * the supplied password. + * + * @param type2 The Type-2 message. + * @param password The password. + * @return A byte[] containing the NT response. + */ + public static byte[] getNTResponse(Type2Message type2, String password) { + if (type2 == null || password == null) return null; + return NtlmPasswordAuthentication.getNTLMResponse(password, + type2.getChallenge()); + } + + /** + * Returns the default domain from the current environment. + * + * @return The default domain. + */ + public static String getDefaultDomain() { + return DEFAULT_DOMAIN; + } + + /** + * Returns the default user from the current environment. + * + * @return The default user. + */ + public static String getDefaultUser() { + return DEFAULT_USER; + } + + /** + * Returns the default password from the current environment. + * + * @return The default password. + */ + public static String getDefaultPassword() { + return DEFAULT_PASSWORD; + } + + /** + * Returns the default workstation from the current environment. + * + * @return The default workstation. + */ + public static String getDefaultWorkstation() { + return DEFAULT_WORKSTATION; + } + + private void parse(byte[] material) throws IOException { + for (int i = 0; i < 8; i++) { + if (material[i] != NTLMSSP_SIGNATURE[i]) { + throw new IOException("Not an NTLMSSP message."); + } + } + if (readULong(material, 8) != 3) { + throw new IOException("Not a Type 3 message."); + } + byte[] lmResponse = readSecurityBuffer(material, 12); + int lmResponseOffset = readULong(material, 16); + byte[] ntResponse = readSecurityBuffer(material, 20); + int ntResponseOffset = readULong(material, 24); + byte[] domain = readSecurityBuffer(material, 28); + int domainOffset = readULong(material, 32); + byte[] user = readSecurityBuffer(material, 36); + int userOffset = readULong(material, 40); + byte[] workstation = readSecurityBuffer(material, 44); + int workstationOffset = readULong(material, 48); + int flags; + String charset; + byte[] _sessionKey = null; + if (lmResponseOffset == 52 || ntResponseOffset == 52 || + domainOffset == 52 || userOffset == 52 || + workstationOffset == 52) { + flags = NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_OEM; + charset = getOEMEncoding(); + } else { + _sessionKey = readSecurityBuffer(material, 52); + flags = readULong(material, 60); + charset = ((flags & NTLMSSP_NEGOTIATE_UNICODE) != 0) ? + UNI_ENCODING : getOEMEncoding(); + } + setSessionKey(_sessionKey); + setFlags(flags); + setLMResponse(lmResponse); + setNTResponse(ntResponse); + setDomain(new String(domain, charset)); + setUser(new String(user, charset)); + setWorkstation(new String(workstation, charset)); + } +} diff --git a/src/jcifs/smb/ACE.java b/src/jcifs/smb/ACE.java new file mode 100644 index 0000000..c656fa8 --- /dev/null +++ b/src/jcifs/smb/ACE.java @@ -0,0 +1,181 @@ +package jcifs.smb; + +import jcifs.util.Hexdump; +import java.io.IOException; + +/** + * An Access Control Entry (ACE) is an element in a security descriptor + * such as those associated with files and directories. The Windows OS + * determines which users have the necessary permissions to access objects + * based on these entries. + *

+ * To fully understand the information exposed by this class a description + * of the access check algorithm used by Windows is required. The following + * is a basic description of the algorithm. For a more complete description + * we recommend reading the section on Access Control in Keith Brown's + * "The .NET Developer's Guide to Windows Security" (which is also + * available online). + *

+ * Direct ACEs are evaluated first in order. The SID of the user performing + * the operation and the desired access bits are compared to the SID + * and access mask of each ACE. If the SID matches, the allow/deny flags + * and access mask are considered. If the ACE is a "deny" + * ACE and any of the desired access bits match bits in the access + * mask of the ACE, the whole access check fails. If the ACE is an "allow" + * ACE and all of the bits in the desired access bits match bits in + * the access mask of the ACE, the access check is successful. Otherwise, + * more ACEs are evaluated until all desired access bits (combined) + * are "allowed". If all of the desired access bits are not "allowed" + * the then same process is repeated for inherited ACEs. + *

+ * For example, if user WNET\alice tries to open a file + * with desired access bits 0x00000003 (FILE_READ_DATA | + * FILE_WRITE_DATA) and the target file has the following security + * descriptor ACEs: + *

+ * Allow WNET\alice     0x001200A9  Direct
+ * Allow Administrators 0x001F01FF  Inherited
+ * Allow SYSTEM         0x001F01FF  Inherited
+ * 
+ * the access check would fail because the direct ACE has an access mask + * of 0x001200A9 which doesn't have the + * FILE_WRITE_DATA bit on (bit 0x00000002). Actually, this isn't quite correct. If + * WNET\alice is in the local Administrators group the access check + * will succeed because the inherited ACE allows local Administrators + * both FILE_READ_DATA and FILE_WRITE_DATA access. + */ + +public class ACE { + + public static final int FILE_READ_DATA = 0x00000001; // 1 + public static final int FILE_WRITE_DATA = 0x00000002; // 2 + public static final int FILE_APPEND_DATA = 0x00000004; // 3 + public static final int FILE_READ_EA = 0x00000008; // 4 + public static final int FILE_WRITE_EA = 0x00000010; // 5 + public static final int FILE_EXECUTE = 0x00000020; // 6 + public static final int FILE_DELETE = 0x00000040; // 7 + public static final int FILE_READ_ATTRIBUTES = 0x00000080; // 8 + public static final int FILE_WRITE_ATTRIBUTES = 0x00000100; // 9 + public static final int DELETE = 0x00010000; // 16 + public static final int READ_CONTROL = 0x00020000; // 17 + public static final int WRITE_DAC = 0x00040000; // 18 + public static final int WRITE_OWNER = 0x00080000; // 19 + public static final int SYNCHRONIZE = 0x00100000; // 20 + public static final int GENERIC_ALL = 0x10000000; // 28 + public static final int GENERIC_EXECUTE = 0x20000000; // 29 + public static final int GENERIC_WRITE = 0x40000000; // 30 + public static final int GENERIC_READ = 0x80000000; // 31 + + public static final int FLAGS_OBJECT_INHERIT = 0x01; + public static final int FLAGS_CONTAINER_INHERIT = 0x02; + public static final int FLAGS_NO_PROPAGATE = 0x04; + public static final int FLAGS_INHERIT_ONLY = 0x08; + public static final int FLAGS_INHERITED = 0x10; + + boolean allow; + int flags; + int access; + SID sid; + + /** + * Returns true if this ACE is an allow ACE and false if it is a deny ACE. + */ + public boolean isAllow() { + return allow; + } + /** + * Returns true if this ACE is an inherited ACE and false if it is a direct ACE. + *

+ * Note: For reasons not fully understood, FLAGS_INHERITED may + * not be set within all security descriptors even though the ACE was in + * face inherited. If an inherited ACE is added to a parent the Windows + * ACL editor will rebuild all children ACEs and set this flag accordingly. + */ + public boolean isInherited() { + return (flags & FLAGS_INHERITED) != 0; + } + /** + * Returns the flags for this ACE. The isInherited() + * method checks the FLAGS_INHERITED bit in these flags. + */ + public int getFlags() { + return flags; + } + /** + * Returns the 'Apply To' text for inheritance of ACEs on + * directories such as 'This folder, subfolder and files'. For + * files the text is always 'This object only'. + */ + public String getApplyToText() { + switch (flags & (FLAGS_OBJECT_INHERIT | FLAGS_CONTAINER_INHERIT | FLAGS_INHERIT_ONLY)) { + case 0x00: + return "This folder only"; + case 0x03: + return "This folder, subfolders and files"; + case 0x0B: + return "Subfolders and files only"; + case 0x02: + return "This folder and subfolders"; + case 0x0A: + return "Subfolders only"; + case 0x01: + return "This folder and files"; + case 0x09: + return "Files only"; + } + return "Invalid"; + } + /** + * Returns the access mask accociated with this ACE. Use the + * constants for FILE_READ_DATA, FILE_WRITE_DATA, + * READ_CONTROL, GENERIC_ALL, etc with bitwise + * operators to determine which bits of the mask are on or off. + */ + public int getAccessMask() { + return access; + } + + /** + * Return the SID associated with this ACE. + */ + public SID getSID() { + return sid; + } + + int decode( byte[] buf, int bi ) { + allow = buf[bi++] == (byte)0x00; + flags = buf[bi++] & 0xFF; + int size = ServerMessageBlock.readInt2(buf, bi); + bi += 2; + access = ServerMessageBlock.readInt4(buf, bi); + bi += 4; + sid = new SID(buf, bi); + return size; + } + + void appendCol(StringBuffer sb, String str, int width) { + sb.append(str); + int count = width - str.length(); + for (int i = 0; i < count; i++) { + sb.append(' '); + } + } + /** + * Return a string represeting this ACE. + *

+ * Note: This function should probably be changed to return SDDL + * fragments but currently it does not. + */ + public String toString() { + int count, i; + String str; + + StringBuffer sb = new StringBuffer(); + sb.append( isAllow() ? "Allow " : "Deny " ); + appendCol(sb, sid.toDisplayString(), 25); + sb.append( " 0x" ).append( Hexdump.toHexString( access, 8 )).append(' '); + sb.append(isInherited() ? "Inherited " : "Direct "); + appendCol(sb, getApplyToText(), 34); + return sb.toString(); + } +} diff --git a/src/jcifs/smb/AllocInfo.java b/src/jcifs/smb/AllocInfo.java new file mode 100644 index 0000000..8f4824d --- /dev/null +++ b/src/jcifs/smb/AllocInfo.java @@ -0,0 +1,24 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +interface AllocInfo { + long getCapacity(); + long getFree(); +} diff --git a/src/jcifs/smb/AndXServerMessageBlock.java b/src/jcifs/smb/AndXServerMessageBlock.java new file mode 100644 index 0000000..fc011ba --- /dev/null +++ b/src/jcifs/smb/AndXServerMessageBlock.java @@ -0,0 +1,303 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.InputStream; +import java.io.IOException; +import jcifs.util.Hexdump; + +abstract class AndXServerMessageBlock extends ServerMessageBlock { + + private static final int ANDX_COMMAND_OFFSET = 1; + private static final int ANDX_RESERVED_OFFSET = 2; + private static final int ANDX_OFFSET_OFFSET = 3; + + private byte andxCommand = (byte)0xFF; + private int andxOffset = 0; + + ServerMessageBlock andx = null; + + AndXServerMessageBlock() { + } + AndXServerMessageBlock( ServerMessageBlock andx ) { + if (andx != null) { + this.andx = andx; + andxCommand = andx.command; + } + } + + int getBatchLimit( byte command ) { + /* the default limit is 0 batched messages before this + * one, meaning this message cannot be batched. + */ + return 0; + } + + /* + * We overload this method from ServerMessageBlock because + * we want writeAndXWireFormat to write the parameterWords + * and bytes. This is so we can write batched smbs because + * all but the first smb of the chaain do not have a header + * and therefore we do not want to writeHeaderWireFormat. We + * just recursivly call writeAndXWireFormat. + */ + + int encode( byte[] dst, int dstIndex ) { + int start = headerStart = dstIndex; + + dstIndex += writeHeaderWireFormat( dst, dstIndex ); + dstIndex += writeAndXWireFormat( dst, dstIndex ); + length = dstIndex - start; + + if( digest != null ) { + digest.sign( dst, headerStart, length, this, response ); + } + + return length; + } + + /* + * We overload this because we want readAndXWireFormat to + * read the parameter words and bytes. This is so when + * commands are batched together we can recursivly call + * readAndXWireFormat without reading the non-existent header. + */ + + int decode( byte[] buffer, int bufferIndex ) { + int start = headerStart = bufferIndex; + + bufferIndex += readHeaderWireFormat( buffer, bufferIndex ); + bufferIndex += readAndXWireFormat( buffer, bufferIndex ); + + length = bufferIndex - start; + return length; + } + int writeAndXWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + wordCount = writeParameterWordsWireFormat( dst, + start + ANDX_OFFSET_OFFSET + 2 ); + wordCount += 4; // for command, reserved, and offset + dstIndex += wordCount + 1; + wordCount /= 2; + dst[start] = (byte)( wordCount & 0xFF ); + + byteCount = writeBytesWireFormat( dst, dstIndex + 2 ); + dst[dstIndex++] = (byte)( byteCount & 0xFF ); + dst[dstIndex++] = (byte)(( byteCount >> 8 ) & 0xFF ); + dstIndex += byteCount; + + /* Normally, without intervention everything would batch + * with everything else. If the below clause evaluates true + * the andx command will not be written and therefore the + * response will not read a batched command and therefore + * the 'received' member of the response object will not + * be set to true indicating the send and sendTransaction + * methods that the next part should be sent. This is a + * very indirect and simple batching control mechanism. + */ + + if( andx == null || USE_BATCHING == false || + batchLevel >= getBatchLimit( andx.command )) { + andxCommand = (byte)0xFF; + andx = null; + + dst[start + ANDX_COMMAND_OFFSET] = (byte)0xFF; + dst[start + ANDX_RESERVED_OFFSET] = (byte)0x00; +// dst[start + ANDX_OFFSET_OFFSET] = (byte)0x00; +// dst[start + ANDX_OFFSET_OFFSET + 1] = (byte)0x00; + dst[start + ANDX_OFFSET_OFFSET] = (byte)0xde; + dst[start + ANDX_OFFSET_OFFSET + 1] = (byte)0xde; + + // andx not used; return + return dstIndex - start; + } + + /* The message provided to batch has a batchLimit that is + * higher than the current batchLevel so we will now encode + * that chained message. Before doing so we must increment + * the batchLevel of the andx message in case it itself is an + * andx message and needs to perform the same check as above. + */ + + andx.batchLevel = batchLevel + 1; + + + dst[start + ANDX_COMMAND_OFFSET] = andxCommand; + dst[start + ANDX_RESERVED_OFFSET] = (byte)0x00; + andxOffset = dstIndex - headerStart; + writeInt2( andxOffset, dst, start + ANDX_OFFSET_OFFSET ); + + andx.useUnicode = useUnicode; + if( andx instanceof AndXServerMessageBlock ) { + + /* + * A word about communicating header info to andx smbs + * + * This is where we recursively invoke the provided andx smb + * object to write it's parameter words and bytes to our outgoing + * array. Incedentally when these andx smbs are created they are not + * necessarily populated with header data because they're not writing + * the header, only their body. But for whatever reason one might wish + * to populate fields if the writeXxx operation needs this header data + * for whatever reason. I copy over the uid here so it appears correct + * in logging output. Logging of andx segments of messages inadvertantly + * print header information because of the way toString always makes a + * super.toString() call(see toString() at the end of all smbs classes). + */ + + andx.uid = uid; + dstIndex += ((AndXServerMessageBlock)andx).writeAndXWireFormat( dst, dstIndex ); + } else { + // the andx smb is not of type andx so lets just write it here and + // were done. + int andxStart = dstIndex; + andx.wordCount = andx.writeParameterWordsWireFormat( dst, dstIndex ); + dstIndex += andx.wordCount + 1; + andx.wordCount /= 2; + dst[andxStart] = (byte)( andx.wordCount & 0xFF ); + + andx.byteCount = andx.writeBytesWireFormat( dst, dstIndex + 2 ); + dst[dstIndex++] = (byte)( andx.byteCount & 0xFF ); + dst[dstIndex++] = (byte)(( andx.byteCount >> 8 ) & 0xFF ); + dstIndex += andx.byteCount; + } + + return dstIndex - start; + } + int readAndXWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + wordCount = buffer[bufferIndex++]; + + if( wordCount != 0 ) { + /* + * these fields are common to all andx commands + * so let's populate them here + */ + + andxCommand = buffer[bufferIndex]; + andxOffset = readInt2( buffer, bufferIndex + 2 ); + + if( andxOffset == 0 ) { /* Snap server workaround */ + andxCommand = (byte)0xFF; + } + + /* + * no point in calling readParameterWordsWireFormat if there are no more + * parameter words. besides, win98 doesn't return "OptionalSupport" field + */ + + if( wordCount > 2 ) { + readParameterWordsWireFormat( buffer, bufferIndex + 4 ); + + /* The SMB_COM_NT_CREATE_ANDX response wordCount is wrong. There's an + * extra 16 bytes for some "Offline Files (CSC or Client Side Caching)" + * junk. We need to bump up the wordCount here so that this method returns + * the correct number of bytes for signing purposes. Otherwise we get a + * signing verification failure. + */ + if (command == SMB_COM_NT_CREATE_ANDX && ((SmbComNTCreateAndXResponse)this).isExtended) + wordCount += 8; + } + + bufferIndex = start + 1 + (wordCount * 2); + } + + byteCount = readInt2( buffer, bufferIndex ); bufferIndex += 2; + + if (byteCount != 0) { + int n; + n = readBytesWireFormat( buffer, bufferIndex ); + bufferIndex += byteCount; + } + + /* + * if there is an andx and it itself is an andx then just recur by + * calling this method for it. otherwise just read it's parameter words + * and bytes as usual. Note how we can't just call andx.readWireFormat + * because there's no header. + */ + + if( errorCode != 0 || andxCommand == (byte)0xFF ) { + andxCommand = (byte)0xFF; + andx = null; + } else if( andx == null ) { + andxCommand = (byte)0xFF; + throw new RuntimeException( "no andx command supplied with response" ); + } else { + + /* + * Set bufferIndex according to andxOffset + */ + + bufferIndex = headerStart + andxOffset; + + andx.headerStart = headerStart; + andx.command = andxCommand; + andx.errorCode = errorCode; + andx.flags = flags; + andx.flags2 = flags2; + andx.tid = tid; + andx.pid = pid; + andx.uid = uid; + andx.mid = mid; + andx.useUnicode = useUnicode; + + if( andx instanceof AndXServerMessageBlock ) { + bufferIndex += ((AndXServerMessageBlock)andx).readAndXWireFormat( + buffer, bufferIndex ); + } else { + + /* + * Just a plain smb. Read it as normal. + */ + + buffer[bufferIndex++] = (byte)( andx.wordCount & 0xFF ); + + if( andx.wordCount != 0 ) { + /* + * no point in calling readParameterWordsWireFormat if there are no more + * parameter words. besides, win98 doesn't return "OptionalSupport" field + */ + + if( andx.wordCount > 2 ) { + bufferIndex += andx.readParameterWordsWireFormat( buffer, bufferIndex ); + } + } + + andx.byteCount = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + + if( andx.byteCount != 0 ) { + andx.readBytesWireFormat( buffer, bufferIndex ); + bufferIndex += andx.byteCount; + } + } + andx.received = true; + } + + return bufferIndex - start; + } + public String toString() { + return new String( super.toString() + + ",andxCommand=0x" + Hexdump.toHexString( andxCommand, 2 ) + + ",andxOffset=" + andxOffset ); + } +} diff --git a/src/jcifs/smb/BufferCache.jav b/src/jcifs/smb/BufferCache.jav new file mode 100644 index 0000000..495869f --- /dev/null +++ b/src/jcifs/smb/BufferCache.jav @@ -0,0 +1,83 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.Config; + +public class BufferCache { + + private static final int MAX_BUFFERS = Config.getInt( "jcifs.smb.maxBuffers", 16 ); + + static Object[] cache = new Object[MAX_BUFFERS]; + private static int freeBuffers = 0; + + private static byte[] getBuffer0() { + byte[] buf; + + if (freeBuffers > 0) { + for (int i = 0; i < MAX_BUFFERS; i++) { + if( cache[i] != null ) { + buf = (byte[])cache[i]; + cache[i] = null; + freeBuffers--; + return buf; + } + } + } + + buf = new byte[SmbComTransaction.TRANSACTION_BUF_SIZE]; + + return buf; + } + + static void getBuffers( SmbComTransaction req, + SmbComTransactionResponse rsp ) throws InterruptedException { + synchronized( cache ) { + if (freeBuffers < 2) { + /* The first time this is called we always wait because freeBuffers + * will be 0. But after a few calls to releaseBuffer, threads will + * no longer wait. + */ + cache.wait(100); + } + req.txn_buf = getBuffer0(); + rsp.txn_buf = getBuffer0(); + } + } + static public byte[] getBuffer() throws InterruptedException { + synchronized( cache ) { + if (freeBuffers < 1) { + cache.wait(100); + } + return getBuffer0(); + } + } + static public void releaseBuffer( byte[] buf ) { + synchronized( cache ) { + for (int i = 0; i < MAX_BUFFERS; i++) { + if (cache[i] == null) { + cache[i] = buf; + freeBuffers++; + cache.notify(); + return; + } + } + } + } +} diff --git a/src/jcifs/smb/BufferCache.java b/src/jcifs/smb/BufferCache.java new file mode 100644 index 0000000..97bd68b --- /dev/null +++ b/src/jcifs/smb/BufferCache.java @@ -0,0 +1,69 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.Config; + +public class BufferCache { + + private static final int MAX_BUFFERS = Config.getInt( "jcifs.smb.maxBuffers", 16 ); + + static Object[] cache = new Object[MAX_BUFFERS]; + private static int freeBuffers = 0; + + static public byte[] getBuffer() { + synchronized( cache ) { + byte[] buf; + + if (freeBuffers > 0) { + for (int i = 0; i < MAX_BUFFERS; i++) { + if( cache[i] != null ) { + buf = (byte[])cache[i]; + cache[i] = null; + freeBuffers--; + return buf; + } + } + } + + buf = new byte[SmbComTransaction.TRANSACTION_BUF_SIZE]; + + return buf; + } + } + static void getBuffers( SmbComTransaction req, SmbComTransactionResponse rsp ) { + synchronized( cache ) { + req.txn_buf = getBuffer(); + rsp.txn_buf = getBuffer(); + } + } + static public void releaseBuffer( byte[] buf ) { + synchronized( cache ) { + if (freeBuffers < MAX_BUFFERS) { + for (int i = 0; i < MAX_BUFFERS; i++) { + if (cache[i] == null) { + cache[i] = buf; + freeBuffers++; + return; + } + } + } + } + } +} diff --git a/src/jcifs/smb/Dfs.java b/src/jcifs/smb/Dfs.java new file mode 100644 index 0000000..f2748b5 --- /dev/null +++ b/src/jcifs/smb/Dfs.java @@ -0,0 +1,327 @@ +/* jcifs smb client library in Java + * Copyright (C) 2008 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.*; +import java.io.*; + +import jcifs.UniAddress; +import jcifs.util.*; +import jcifs.Config; + +public class Dfs { + + static class CacheEntry { + long expiration; + HashMap map; + + CacheEntry(long ttl) { + if (ttl == 0) + ttl = Dfs.TTL; + expiration = System.currentTimeMillis() + ttl * 1000L; + map = new HashMap(); + } + } + + static LogStream log = LogStream.getInstance(); + static final boolean strictView = Config.getBoolean("jcifs.smb.client.dfs.strictView", false); + static final long TTL = Config.getLong("jcifs.smb.client.dfs.ttl", 300); + static final boolean DISABLED = Config.getBoolean("jcifs.smb.client.dfs.disabled", false); + + protected static CacheEntry FALSE_ENTRY = new Dfs.CacheEntry(0L); + + protected CacheEntry _domains = null; /* aka trusted domains cache */ + protected CacheEntry referrals = null; + + public HashMap getTrustedDomains(NtlmPasswordAuthentication auth) throws SmbAuthException { + if (DISABLED || auth.domain == "?") + return null; + + if (_domains != null && System.currentTimeMillis() > _domains.expiration) { + _domains = null; + } + if (_domains != null) + return _domains.map; + try { + UniAddress addr = UniAddress.getByName(auth.domain, true); + SmbTransport trans = SmbTransport.getSmbTransport(addr, 0); + CacheEntry entry = new CacheEntry(Dfs.TTL * 10L); + + DfsReferral dr = trans.getDfsReferrals(auth, "", 0); + if (dr != null) { + DfsReferral start = dr; + do { + String domain = dr.server.toLowerCase(); + entry.map.put(domain, new HashMap()); + dr = dr.next; + } while (dr != start); + + _domains = entry; + return _domains.map; + } + } catch (IOException ioe) { + if (log.level >= 3) + ioe.printStackTrace(log); + if (strictView && ioe instanceof SmbAuthException) { + throw (SmbAuthException)ioe; + } + } + return null; + } + public boolean isTrustedDomain(String domain, + NtlmPasswordAuthentication auth) throws SmbAuthException + { + HashMap domains = getTrustedDomains(auth); + if (domains == null) + return false; + domain = domain.toLowerCase(); + return domains.get(domain) != null; + } + public SmbTransport getDc(String domain, + NtlmPasswordAuthentication auth) throws SmbAuthException { + if (DISABLED) + return null; + + try { + UniAddress addr = UniAddress.getByName(domain, true); + SmbTransport trans = SmbTransport.getSmbTransport(addr, 0); + DfsReferral dr = trans.getDfsReferrals(auth, "\\" + domain, 1); + if (dr != null) { + DfsReferral start = dr; + IOException e = null; + + do { + try { + addr = UniAddress.getByName(dr.server); + return SmbTransport.getSmbTransport(addr, 0); + } catch (IOException ioe) { + e = ioe; + } + + dr = dr.next; + } while (dr != start); + + throw e; + } + } catch (IOException ioe) { + if (log.level >= 3) + ioe.printStackTrace(log); + if (strictView && ioe instanceof SmbAuthException) { + throw (SmbAuthException)ioe; + } + } + return null; + } + public DfsReferral getReferral(SmbTransport trans, + String domain, + String root, + String path, + NtlmPasswordAuthentication auth) throws SmbAuthException { + if (DISABLED) + return null; + + try { + String p = "\\" + domain + "\\" + root; + if (path != null) + p += path; + DfsReferral dr = trans.getDfsReferrals(auth, p, 0); + if (dr != null) + return dr; + } catch (IOException ioe) { + if (log.level >= 4) + ioe.printStackTrace(log); + if (strictView && ioe instanceof SmbAuthException) { + throw (SmbAuthException)ioe; + } + } + return null; + } + public synchronized DfsReferral resolve(String domain, + String root, + String path, + NtlmPasswordAuthentication auth) throws SmbAuthException { + DfsReferral dr = null; + long now = System.currentTimeMillis(); + + if (DISABLED || root.equals("IPC$")) { + return null; + } + /* domains that can contain DFS points to maps of roots for each + */ + HashMap domains = getTrustedDomains(auth); + if (domains != null) { + domain = domain.toLowerCase(); + /* domain-based DFS root shares to links for each + */ + HashMap roots = (HashMap)domains.get(domain); + if (roots != null) { + SmbTransport trans = null; + + root = root.toLowerCase(); + + /* The link entries contain maps of referrals by path representing DFS links. + * Note that paths are relative to the root like "\" and not "\example.com\root". + */ + CacheEntry links = (CacheEntry)roots.get(root); + if (links != null && now > links.expiration) { + roots.remove(root); + links = null; + } + + if (links == null) { + if ((trans = getDc(domain, auth)) == null) + return null; + + dr = getReferral(trans, domain, root, path, auth); + if (dr != null) { + int len = 1 + domain.length() + 1 + root.length(); + + links = new CacheEntry(0L); + + DfsReferral tmp = dr; + do { + if (path == null) { + /* Store references to the map and key so that + * SmbFile.resolveDfs can re-insert the dr list with + * the dr that was successful so that subsequent + * attempts to resolve DFS use the last successful + * referral first. + */ + tmp.map = links.map; + tmp.key = "\\"; + } + tmp.pathConsumed -= len; + tmp = tmp.next; + } while (tmp != dr); + + if (dr.key != null) + links.map.put(dr.key, dr); + + roots.put(root, links); + } else if (path == null) { + roots.put(root, Dfs.FALSE_ENTRY); + } + } else if (links == Dfs.FALSE_ENTRY) { + links = null; + } + + if (links != null) { + String link = "\\"; + + /* Lookup the domain based DFS root target referral. Note the + * path is just "\" and not "\example.com\root". + */ + dr = (DfsReferral)links.map.get(link); + if (dr != null && now > dr.expiration) { + links.map.remove(link); + dr = null; + } + + if (dr == null) { + if (trans == null) + if ((trans = getDc(domain, auth)) == null) + return null; + dr = getReferral(trans, domain, root, path, auth); + if (dr != null) { + dr.pathConsumed -= 1 + domain.length() + 1 + root.length(); + dr.link = link; + links.map.put(link, dr); + } + } + } + } + } + + if (dr == null && path != null) { + /* We did not match a domain based root. Now try to match the + * longest path in the list of stand-alone referrals. + */ + if (referrals != null && now > referrals.expiration) { + referrals = null; + } + if (referrals == null) { + referrals = new CacheEntry(0); + } + String key = "\\" + domain + "\\" + root; + if (path.equals("\\") == false) + key += path; + key = key.toLowerCase(); + + Iterator iter = referrals.map.keySet().iterator(); + while (iter.hasNext()) { + String _key = (String)iter.next(); + int _klen = _key.length(); + boolean match = false; + + if (_klen == key.length()) { + match = _key.equals(key); + } else if (_klen < key.length()) { + match = _key.regionMatches(0, key, 0, _klen) && key.charAt(_klen) == '\\'; + } + + if (match) + dr = (DfsReferral)referrals.map.get(_key); + } + } + + return dr; + } + synchronized void insert(String path, DfsReferral dr) { + int s1, s2; + String server, share, key; + + if (DISABLED) + return; + + s1 = path.indexOf('\\', 1); + s2 = path.indexOf('\\', s1 + 1); + server = path.substring(1, s1); + share = path.substring(s1 + 1, s2); + + key = path.substring(0, dr.pathConsumed).toLowerCase(); + + /* Samba has a tendency to return referral paths and pathConsumed values + * in such a way that there can be a slash at the end of the path. This + * causes problems matching keys in resolve() where an extra slash causes + * a mismatch. This strips trailing slashes from all keys to eliminate + * this problem. + */ + int ki = key.length(); + while (ki > 1 && key.charAt(ki - 1) == '\\') { + ki--; + } + if (ki < key.length()) { + key = key.substring(0, ki); + } + + /* Subtract the server and share from the pathConsumed so that + * it refects the part of the relative path consumed and not + * the entire path. + */ + dr.pathConsumed -= 1 + server.length() + 1 + share.length(); + + if (referrals != null && (System.currentTimeMillis() + 10000) > referrals.expiration) { + referrals = null; + } + if (referrals == null) { + referrals = new CacheEntry(0); + } + referrals.map.put(key, dr); + } +} diff --git a/src/jcifs/smb/DfsReferral.java b/src/jcifs/smb/DfsReferral.java new file mode 100644 index 0000000..27e0493 --- /dev/null +++ b/src/jcifs/smb/DfsReferral.java @@ -0,0 +1,59 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Map; + +public class DfsReferral extends SmbException { + + public int pathConsumed; + public long ttl; + public String server; // Server + public String share; // Share + public String link; + public String path; // Path relative to tree from which this referral was thrown + public boolean resolveHashes; + public long expiration; + + DfsReferral next; + Map map; + String key = null; + + public DfsReferral() + { + this.next = this; + } + + void append(DfsReferral dr) + { + dr.next = next; + next = dr; + } + + public String toString() { + return "DfsReferral[pathConsumed=" + pathConsumed + + ",server=" + server + + ",share=" + share + + ",link=" + link + + ",path=" + path + + ",ttl=" + ttl + + ",expiration=" + expiration + + ",resolveHashes=" + resolveHashes + "]"; + } +} diff --git a/src/jcifs/smb/DosError.java b/src/jcifs/smb/DosError.java new file mode 100644 index 0000000..5543e56 --- /dev/null +++ b/src/jcifs/smb/DosError.java @@ -0,0 +1,112 @@ +/* jcifs smb client library in Java + * Copyright (C) 2004 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +public interface DosError { + + static final int[][] DOS_ERROR_CODES = { + { 0x00000000, 0x00000000 }, + { 0x00010001, 0xc0000002 }, + { 0x00010002, 0xc0000002 }, + { 0x00020001, 0xc000000f }, + { 0x00020002, 0xc000006a }, + { 0x00030001, 0xc000003a }, + { 0x00030002, 0xc00000cb }, + { 0x00040002, 0xc00000ca }, + { 0x00050001, 0xc0000022 }, + { 0x00050002, 0xc000000d }, + { 0x00060001, 0xc0000008 }, + { 0x00060002, 0xc00000cc }, + { 0x00080001, 0xc000009a }, + { 0x00130003, 0xc00000a2 }, + { 0x00150003, 0xc0000013 }, + { 0x001f0001, 0xc0000001 }, + { 0x001f0003, 0xc0000001 }, + { 0x00200001, 0xc0000043 }, + { 0x00200003, 0xc0000043 }, + { 0x00210003, 0xc0000054 }, + { 0x00270003, 0xc000007f }, + { 0x00340001, 0xC00000bd }, + { 0x00430001, 0xc00000cc }, + { 0x00470001, 0xC00000d0 }, + { 0x00500001, 0xc0000035 }, + { 0x00570001, 0xc0000003 }, + { 0x005a0002, 0xc00000ce }, + { 0x005b0002, 0xc000000d }, + { 0x006d0001, 0xC000014b }, + { 0x007b0001, 0xc0000033 }, + { 0x00910001, 0xC0000101 }, + { 0x00b70001, 0xc0000035 }, + { 0x00e70001, 0xc00000ab }, + { 0x00e80001, 0xc00000b1 }, + { 0x00e90001, 0xc00000b0 }, + { 0x00ea0001, 0xc0000016 }, + { 0x08bf0002, 0xC0000193 }, + { 0x08c00002, 0xC0000070 }, + { 0x08c10002, 0xC000006f }, + { 0x08c20002, 0xC0000071 }, + }; + + /* These aren't really used by jCIFS -- the map above is used + * to immediately map to NTSTATUS codes. + */ + static final String[] DOS_ERROR_MESSAGES = { + "The operation completed successfully.", + "Incorrect function.", + "Incorrect function.", + "The system cannot find the file specified.", + "Bad password.", + "The system cannot find the path specified.", + "reserved", + "The client does not have the necessary access rights to perform the requested function.", + "Access is denied.", + "The TID specified was invalid.", + "The handle is invalid.", + "The network name cannot be found.", + "Not enough storage is available to process this command.", + "The media is write protected.", + "The device is not ready.", + "A device attached to the system is not functioning.", + "A device attached to the system is not functioning.", + "The process cannot access the file because it is being used by another process.", + "The process cannot access the file because it is being used by another process.", + "The process cannot access the file because another process has locked a portion of the file.", + "The disk is full.", + "A duplicate name exists on the network.", + "The network name cannot be found.", + "ERRnomoreconn.", + "The file exists.", + "The parameter is incorrect.", + "Too many Uids active on this session.", + "The Uid is not known as a valid user identifier on this session.", + "The pipe has been ended.", + "The filename, directory name, or volume label syntax is incorrect.", + "The directory is not empty.", + "Cannot create a file when that file already exists.", + "All pipe instances are busy.", + "The pipe is being closed.", + "No process is on the other end of the pipe.", + "More data is available.", + "This user account has expired.", + "The user is not allowed to log on from this workstation.", + "The user is not allowed to log on at this time.", + "The password of this user has expired.", + }; +} + diff --git a/src/jcifs/smb/DosFileFilter.java b/src/jcifs/smb/DosFileFilter.java new file mode 100644 index 0000000..7a76562 --- /dev/null +++ b/src/jcifs/smb/DosFileFilter.java @@ -0,0 +1,46 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +public class DosFileFilter implements SmbFileFilter { + + protected String wildcard; + protected int attributes; + +/* This filter can be considerably more efficient than other file filters + * as the specifed wildcard and attributes are passed to the server for + * filtering there (although attributes are largely ignored by servers + * they are filtered locally by the default accept method). + */ + public DosFileFilter( String wildcard, int attributes ) { + this.wildcard = wildcard; + this.attributes = attributes; + } + +/* This returns true if the file's attributes contain any of the attributes + * specified for this filter. The wildcard has no influence on this + * method as the server should have performed that filtering already. The + * attributes are asserted here only because server file systems may not + * support filtering by all attributes (e.g. even though ATTR_DIRECTORY was + * specified the server may still return objects that are not directories). + */ + public boolean accept( SmbFile file ) throws SmbException { + return (file.getAttributes() & attributes) != 0; + } +} diff --git a/src/jcifs/smb/FileEntry.java b/src/jcifs/smb/FileEntry.java new file mode 100644 index 0000000..d26088f --- /dev/null +++ b/src/jcifs/smb/FileEntry.java @@ -0,0 +1,11 @@ +package jcifs.smb; + +public interface FileEntry { + + String getName(); + int getType(); + int getAttributes(); + long createTime(); + long lastModified(); + long length(); +} diff --git a/src/jcifs/smb/Handler.java b/src/jcifs/smb/Handler.java new file mode 100644 index 0000000..5ab66cc --- /dev/null +++ b/src/jcifs/smb/Handler.java @@ -0,0 +1,65 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.io.PrintStream; + +public class Handler extends URLStreamHandler { + + static final URLStreamHandler SMB_HANDLER = new Handler(); + + protected int getDefaultPort() { + return SmbConstants.DEFAULT_PORT; + } + public URLConnection openConnection( URL u ) throws IOException { + return new SmbFile( u ); + } + protected void parseURL( URL u, String spec, int start, int limit ) { + String host = u.getHost(); + String path, ref; + int port; + + if( spec.equals( "smb://" )) { + spec = "smb:////"; + limit += 2; + } else if( spec.startsWith( "smb://" ) == false && + host != null && host.length() == 0 ) { + spec = "//" + spec; + limit += 2; + } + super.parseURL( u, spec, start, limit ); + path = u.getPath(); + ref = u.getRef(); + if (ref != null) { + path += '#' + ref; + } + port = u.getPort(); + if( port == -1 ) { + port = getDefaultPort(); + } + setURL( u, "smb", u.getHost(), port, + u.getAuthority(), u.getUserInfo(), + path, u.getQuery(), null ); + } +} diff --git a/src/jcifs/smb/Info.java b/src/jcifs/smb/Info.java new file mode 100644 index 0000000..13437b7 --- /dev/null +++ b/src/jcifs/smb/Info.java @@ -0,0 +1,26 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +interface Info { + int getAttributes(); + long getCreateTime(); + long getLastWriteTime(); + long getSize(); +} diff --git a/src/jcifs/smb/NetServerEnum2.java b/src/jcifs/smb/NetServerEnum2.java new file mode 100644 index 0000000..6d1067a --- /dev/null +++ b/src/jcifs/smb/NetServerEnum2.java @@ -0,0 +1,107 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * Gary Rambo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.UnsupportedEncodingException; + +class NetServerEnum2 extends SmbComTransaction { + + static final int SV_TYPE_ALL = 0xFFFFFFFF; + static final int SV_TYPE_DOMAIN_ENUM = 0x80000000; + + static final String[] DESCR = { + "WrLehDz\u0000B16BBDz\u0000", + "WrLehDzz\u0000B16BBDz\u0000" + }; + + String domain, lastName = null; + int serverTypes; + + NetServerEnum2( String domain, int serverTypes ) { + this.domain = domain; + this.serverTypes = serverTypes; + command = SMB_COM_TRANSACTION; + subCommand = NET_SERVER_ENUM2; // not really true be used by upper logic + name = "\\PIPE\\LANMAN"; + + maxParameterCount = 8; +// maxDataCount = 4096; why was this here? +maxDataCount = 16384; + maxSetupCount = (byte)0x00; + setupCount = 0; + timeout = 5000; + } + + void reset( int key, String lastName ) { + super.reset(); + this.lastName = lastName; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + byte[] descr; + int which = subCommand == NET_SERVER_ENUM2 ? 0 : 1; + + try { + descr = DESCR[which].getBytes( "ASCII" ); + } catch( UnsupportedEncodingException uee ) { + return 0; + } + + writeInt2( subCommand & 0xFF, dst, dstIndex ); + dstIndex += 2; + System.arraycopy( descr, 0, dst, dstIndex, descr.length ); + dstIndex += descr.length; + writeInt2( 0x0001, dst, dstIndex ); + dstIndex += 2; + writeInt2( maxDataCount, dst, dstIndex ); + dstIndex += 2; + writeInt4( serverTypes, dst, dstIndex ); + dstIndex += 4; + dstIndex += writeString( domain.toUpperCase(), dst, dstIndex, false ); + if( which == 1 ) { + dstIndex += writeString( lastName.toUpperCase(), dst, dstIndex, false ); + } + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "NetServerEnum2[" + super.toString() + + ",name=" + name + + ",serverTypes=" + (serverTypes == SV_TYPE_ALL ? + "SV_TYPE_ALL" : "SV_TYPE_DOMAIN_ENUM" ) + + "]" ); + } +} diff --git a/src/jcifs/smb/NetServerEnum2Response.java b/src/jcifs/smb/NetServerEnum2Response.java new file mode 100644 index 0000000..3ee9bfe --- /dev/null +++ b/src/jcifs/smb/NetServerEnum2Response.java @@ -0,0 +1,132 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * Gary Rambo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.InputStream; +import java.io.IOException; +import jcifs.util.Hexdump; + +class NetServerEnum2Response extends SmbComTransactionResponse { + + class ServerInfo1 implements FileEntry { + String name; + int versionMajor; + int versionMinor; + int type; + String commentOrMasterBrowser; + + public String getName() { + return name; + } + public int getType() { + return (type & 0x80000000) != 0 ? SmbFile.TYPE_WORKGROUP : SmbFile.TYPE_SERVER; + } + public int getAttributes() { + return SmbFile.ATTR_READONLY | SmbFile.ATTR_DIRECTORY; + } + public long createTime() { + return 0L; + } + public long lastModified() { + return 0L; + } + public long length() { + return 0L; + } + + public String toString() { + return new String( "ServerInfo1[" + + "name=" + name + + ",versionMajor=" + versionMajor + + ",versionMinor=" + versionMinor + + ",type=0x" + Hexdump.toHexString( type, 8 ) + + ",commentOrMasterBrowser=" + commentOrMasterBrowser + "]" ); + } + } + + private int converter, totalAvailableEntries; + + String lastName; + + NetServerEnum2Response() { + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + + status = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + converter = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + numEntries = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + totalAvailableEntries = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + + return bufferIndex - start; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + ServerInfo1 e = null; + + results = new ServerInfo1[numEntries]; + for( int i = 0; i < numEntries; i++ ) { + results[i] = e = new ServerInfo1(); + e.name = readString( buffer, bufferIndex, 16, false ); + bufferIndex += 16; + e.versionMajor = (int)( buffer[bufferIndex++] & 0xFF ); + e.versionMinor = (int)( buffer[bufferIndex++] & 0xFF ); + e.type = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + int off = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + off = ( off & 0xFFFF ) - converter; + off = start + off; + e.commentOrMasterBrowser = readString( buffer, off, 48, false ); + + if( log.level >= 4 ) + log.println( e ); + } + lastName = numEntries == 0 ? null : e.name; + + return bufferIndex - start; + } + public String toString() { + return new String( "NetServerEnum2Response[" + + super.toString() + + ",status=" + status + + ",converter=" + converter + + ",entriesReturned=" + numEntries + + ",totalAvailableEntries=" + totalAvailableEntries + + ",lastName=" + lastName + "]" ); + } +} diff --git a/src/jcifs/smb/NetShareEnum.java b/src/jcifs/smb/NetShareEnum.java new file mode 100644 index 0000000..524bf82 --- /dev/null +++ b/src/jcifs/smb/NetShareEnum.java @@ -0,0 +1,78 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.UnsupportedEncodingException; + +class NetShareEnum extends SmbComTransaction { + + private static final String DESCR = "WrLeh\u0000B13BWz\u0000"; + + NetShareEnum() { + command = SMB_COM_TRANSACTION; + subCommand = NET_SHARE_ENUM; // not really true be used by upper logic + name = new String( "\\PIPE\\LANMAN" ); + maxParameterCount = 8; + +// maxDataCount = 4096; why was this set? + maxSetupCount = (byte)0x00; + setupCount = 0; + timeout = 5000; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + byte[] descr; + + try { + descr = DESCR.getBytes( "ASCII" ); + } catch( UnsupportedEncodingException uee ) { + return 0; + } + + writeInt2( NET_SHARE_ENUM, dst, dstIndex ); + dstIndex += 2; + System.arraycopy( descr, 0, dst, dstIndex, descr.length ); + dstIndex += descr.length; + writeInt2( 0x0001, dst, dstIndex ); + dstIndex += 2; + writeInt2( maxDataCount, dst, dstIndex ); + dstIndex += 2; + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "NetShareEnum[" + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/NetShareEnumResponse.java b/src/jcifs/smb/NetShareEnumResponse.java new file mode 100644 index 0000000..975754d --- /dev/null +++ b/src/jcifs/smb/NetShareEnumResponse.java @@ -0,0 +1,91 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.InputStream; +import java.io.IOException; +import jcifs.util.Hexdump; + +class NetShareEnumResponse extends SmbComTransactionResponse { + + private int converter, totalAvailableEntries; + + NetShareEnumResponse() { + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + + status = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + converter = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + numEntries = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + totalAvailableEntries = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + + return bufferIndex - start; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + SmbShareInfo e; + + useUnicode = false; + + results = new SmbShareInfo[numEntries]; + for( int i = 0; i < numEntries; i++ ) { + results[i] = e = new SmbShareInfo(); + e.netName = readString( buffer, bufferIndex, 13, false ); + bufferIndex += 14; + e.type = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + int off = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + off = ( off & 0xFFFF ) - converter; + off = start + off; + e.remark = readString( buffer, off, 128, false ); + + if (log.level >= 4) + log.println( e ); + } + + return bufferIndex - start; + } + public String toString() { + return new String( "NetShareEnumResponse[" + + super.toString() + + ",status=" + status + + ",converter=" + converter + + ",entriesReturned=" + numEntries + + ",totalAvailableEntries=" + totalAvailableEntries + "]" ); + } +} diff --git a/src/jcifs/smb/NtStatus.java b/src/jcifs/smb/NtStatus.java new file mode 100644 index 0000000..74456b8 --- /dev/null +++ b/src/jcifs/smb/NtStatus.java @@ -0,0 +1,220 @@ +/* jcifs smb client library in Java + * Copyright (C) 2004 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +public interface NtStatus { + + /* Don't bother to edit this. Everthing within the interface + * block is automatically generated from the ntstatus package. + */ + + public static final int NT_STATUS_OK = 0x00000000; + public static final int NT_STATUS_UNSUCCESSFUL = 0xC0000001; + public static final int NT_STATUS_NOT_IMPLEMENTED = 0xC0000002; + public static final int NT_STATUS_INVALID_INFO_CLASS = 0xC0000003; + public static final int NT_STATUS_ACCESS_VIOLATION = 0xC0000005; + public static final int NT_STATUS_INVALID_HANDLE = 0xC0000008; + public static final int NT_STATUS_INVALID_PARAMETER = 0xC000000d; + public static final int NT_STATUS_NO_SUCH_DEVICE = 0xC000000e; + public static final int NT_STATUS_NO_SUCH_FILE = 0xC000000f; + public static final int NT_STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016; + public static final int NT_STATUS_ACCESS_DENIED = 0xC0000022; + public static final int NT_STATUS_BUFFER_TOO_SMALL = 0xC0000023; + public static final int NT_STATUS_OBJECT_NAME_INVALID = 0xC0000033; + public static final int NT_STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034; + public static final int NT_STATUS_OBJECT_NAME_COLLISION = 0xC0000035; + public static final int NT_STATUS_PORT_DISCONNECTED = 0xC0000037; + public static final int NT_STATUS_OBJECT_PATH_INVALID = 0xC0000039; + public static final int NT_STATUS_OBJECT_PATH_NOT_FOUND = 0xC000003a; + public static final int NT_STATUS_OBJECT_PATH_SYNTAX_BAD = 0xC000003b; + public static final int NT_STATUS_SHARING_VIOLATION = 0xC0000043; + public static final int NT_STATUS_DELETE_PENDING = 0xC0000056; + public static final int NT_STATUS_NO_LOGON_SERVERS = 0xC000005e; + public static final int NT_STATUS_USER_EXISTS = 0xC0000063; + public static final int NT_STATUS_NO_SUCH_USER = 0xC0000064; + public static final int NT_STATUS_WRONG_PASSWORD = 0xC000006a; + public static final int NT_STATUS_LOGON_FAILURE = 0xC000006d; + public static final int NT_STATUS_ACCOUNT_RESTRICTION = 0xC000006e; + public static final int NT_STATUS_INVALID_LOGON_HOURS = 0xC000006f; + public static final int NT_STATUS_INVALID_WORKSTATION = 0xC0000070; + public static final int NT_STATUS_PASSWORD_EXPIRED = 0xC0000071; + public static final int NT_STATUS_ACCOUNT_DISABLED = 0xC0000072; + public static final int NT_STATUS_NONE_MAPPED = 0xC0000073; + public static final int NT_STATUS_INVALID_SID = 0xC0000078; + public static final int NT_STATUS_INSTANCE_NOT_AVAILABLE = 0xC00000ab; + public static final int NT_STATUS_PIPE_NOT_AVAILABLE = 0xC00000ac; + public static final int NT_STATUS_INVALID_PIPE_STATE = 0xC00000ad; + public static final int NT_STATUS_PIPE_BUSY = 0xC00000ae; + public static final int NT_STATUS_PIPE_DISCONNECTED = 0xC00000b0; + public static final int NT_STATUS_PIPE_CLOSING = 0xC00000b1; + public static final int NT_STATUS_PIPE_LISTENING = 0xC00000b3; + public static final int NT_STATUS_FILE_IS_A_DIRECTORY = 0xC00000ba; + public static final int NT_STATUS_DUPLICATE_NAME = 0xC00000bd; + public static final int NT_STATUS_NETWORK_NAME_DELETED = 0xC00000c9; + public static final int NT_STATUS_NETWORK_ACCESS_DENIED = 0xC00000ca; + public static final int NT_STATUS_BAD_NETWORK_NAME = 0xC00000cc; + public static final int NT_STATUS_REQUEST_NOT_ACCEPTED = 0xC00000d0; + public static final int NT_STATUS_CANT_ACCESS_DOMAIN_INFO = 0xC00000da; + public static final int NT_STATUS_NO_SUCH_DOMAIN = 0xC00000df; + public static final int NT_STATUS_NOT_A_DIRECTORY = 0xC0000103; + public static final int NT_STATUS_CANNOT_DELETE = 0xC0000121; + public static final int NT_STATUS_INVALID_COMPUTER_NAME = 0xC0000122; + public static final int NT_STATUS_PIPE_BROKEN = 0xC000014b; + public static final int NT_STATUS_NO_SUCH_ALIAS = 0xC0000151; + public static final int NT_STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015b; + public static final int NT_STATUS_NO_TRUST_SAM_ACCOUNT = 0xC000018b; + public static final int NT_STATUS_TRUSTED_DOMAIN_FAILURE = 0xC000018c; + public static final int NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT = 0xC0000199; + public static final int NT_STATUS_PASSWORD_MUST_CHANGE = 0xC0000224; + public static final int NT_STATUS_NOT_FOUND = 0xC0000225; + public static final int NT_STATUS_ACCOUNT_LOCKED_OUT = 0xC0000234; + public static final int NT_STATUS_PATH_NOT_COVERED = 0xC0000257; + public static final int NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED = 0xC0000279; + + static final int[] NT_STATUS_CODES = { + NT_STATUS_OK, + NT_STATUS_UNSUCCESSFUL, + NT_STATUS_NOT_IMPLEMENTED, + NT_STATUS_INVALID_INFO_CLASS, + NT_STATUS_ACCESS_VIOLATION, + NT_STATUS_INVALID_HANDLE, + NT_STATUS_INVALID_PARAMETER, + NT_STATUS_NO_SUCH_DEVICE, + NT_STATUS_NO_SUCH_FILE, + NT_STATUS_MORE_PROCESSING_REQUIRED, + NT_STATUS_ACCESS_DENIED, + NT_STATUS_BUFFER_TOO_SMALL, + NT_STATUS_OBJECT_NAME_INVALID, + NT_STATUS_OBJECT_NAME_NOT_FOUND, + NT_STATUS_OBJECT_NAME_COLLISION, + NT_STATUS_PORT_DISCONNECTED, + NT_STATUS_OBJECT_PATH_INVALID, + NT_STATUS_OBJECT_PATH_NOT_FOUND, + NT_STATUS_OBJECT_PATH_SYNTAX_BAD, + NT_STATUS_SHARING_VIOLATION, + NT_STATUS_DELETE_PENDING, + NT_STATUS_NO_LOGON_SERVERS, + NT_STATUS_USER_EXISTS, + NT_STATUS_NO_SUCH_USER, + NT_STATUS_WRONG_PASSWORD, + NT_STATUS_LOGON_FAILURE, + NT_STATUS_ACCOUNT_RESTRICTION, + NT_STATUS_INVALID_LOGON_HOURS, + NT_STATUS_INVALID_WORKSTATION, + NT_STATUS_PASSWORD_EXPIRED, + NT_STATUS_ACCOUNT_DISABLED, + NT_STATUS_NONE_MAPPED, + NT_STATUS_INVALID_SID, + NT_STATUS_INSTANCE_NOT_AVAILABLE, + NT_STATUS_PIPE_NOT_AVAILABLE, + NT_STATUS_INVALID_PIPE_STATE, + NT_STATUS_PIPE_BUSY, + NT_STATUS_PIPE_DISCONNECTED, + NT_STATUS_PIPE_CLOSING, + NT_STATUS_PIPE_LISTENING, + NT_STATUS_FILE_IS_A_DIRECTORY, + NT_STATUS_DUPLICATE_NAME, + NT_STATUS_NETWORK_NAME_DELETED, + NT_STATUS_NETWORK_ACCESS_DENIED, + NT_STATUS_BAD_NETWORK_NAME, + NT_STATUS_REQUEST_NOT_ACCEPTED, + NT_STATUS_CANT_ACCESS_DOMAIN_INFO, + NT_STATUS_NO_SUCH_DOMAIN, + NT_STATUS_NOT_A_DIRECTORY, + NT_STATUS_CANNOT_DELETE, + NT_STATUS_INVALID_COMPUTER_NAME, + NT_STATUS_PIPE_BROKEN, + NT_STATUS_NO_SUCH_ALIAS, + NT_STATUS_LOGON_TYPE_NOT_GRANTED, + NT_STATUS_NO_TRUST_SAM_ACCOUNT, + NT_STATUS_TRUSTED_DOMAIN_FAILURE, + NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT, + NT_STATUS_PASSWORD_MUST_CHANGE, + NT_STATUS_NOT_FOUND, + NT_STATUS_ACCOUNT_LOCKED_OUT, + NT_STATUS_PATH_NOT_COVERED, + NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED, + }; + + static final String[] NT_STATUS_MESSAGES = { + "The operation completed successfully.", + "A device attached to the system is not functioning.", + "Incorrect function.", + "The parameter is incorrect.", + "Invalid access to memory location.", + "The handle is invalid.", + "The parameter is incorrect.", + "The system cannot find the file specified.", + "The system cannot find the file specified.", + "More data is available.", + "Access is denied.", + "The data area passed to a system call is too small.", + "The filename, directory name, or volume label syntax is incorrect.", + "The system cannot find the file specified.", + "Cannot create a file when that file already exists.", + "The handle is invalid.", + "The specified path is invalid.", + "The system cannot find the path specified.", + "The specified path is invalid.", + "The process cannot access the file because it is being used by another process.", + "Access is denied.", + "There are currently no logon servers available to service the logon request.", + "The specified user already exists.", + "The specified user does not exist.", + "The specified network password is not correct.", + "Logon failure: unknown user name or bad password.", + "Logon failure: user account restriction.", + "Logon failure: account logon time restriction violation.", + "Logon failure: user not allowed to log on to this computer.", + "Logon failure: the specified account password has expired.", + "Logon failure: account currently disabled.", + "No mapping between account names and security IDs was done.", + "The security ID structure is invalid.", + "All pipe instances are busy.", + "All pipe instances are busy.", + "The pipe state is invalid.", + "All pipe instances are busy.", + "No process is on the other end of the pipe.", + "The pipe is being closed.", + "Waiting for a process to open the other end of the pipe.", + "Access is denied.", + "A duplicate name exists on the network.", + "The specified network name is no longer available.", + "Network access is denied.", + "The network name cannot be found.", + "No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept.", + "Indicates a Windows NT Server could not be contacted or that objects within the domain are protected such that necessary information could not be retrieved.", + "The specified domain did not exist.", + "The directory name is invalid.", + "Access is denied.", + "The format of the specified computer name is invalid.", + "The pipe has been ended.", + "The specified local group does not exist.", + "Logon failure: the user has not been granted the requested logon type at this computer.", + "The SAM database on the Windows NT Server does not have a computer account for this workstation trust relationship.", + "The trust relationship between the primary domain and the trusted domain failed.", + "The account used is a Computer Account. Use your global user account or local user account to access this server.", + "The user must change his password before he logs on the first time.", + "NT_STATUS_NOT_FOUND", + "The referenced account is currently locked out and may not be logged on to.", + "The remote system is not reachable by the transport.", + "NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED", + }; +} + diff --git a/src/jcifs/smb/NtTransQuerySecurityDesc.java b/src/jcifs/smb/NtTransQuerySecurityDesc.java new file mode 100644 index 0000000..b6900a3 --- /dev/null +++ b/src/jcifs/smb/NtTransQuerySecurityDesc.java @@ -0,0 +1,72 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.util.Hexdump; + +class NtTransQuerySecurityDesc extends SmbComNtTransaction { + + int fid; + int securityInformation; + + NtTransQuerySecurityDesc( int fid, int securityInformation ) { + this.fid = fid; + this.securityInformation = securityInformation; + command = SMB_COM_NT_TRANSACT; + function = NT_TRANSACT_QUERY_SECURITY_DESC; + setupCount = 0; + totalDataCount = 0; + maxParameterCount = 4; + maxDataCount = 32768; + maxSetupCount = (byte)0x00; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( fid, dst, dstIndex ); + dstIndex += 2; + dst[dstIndex++] = (byte)0x00; // Reserved + dst[dstIndex++] = (byte)0x00; // Reserved + writeInt4( securityInformation, dst, dstIndex ); + dstIndex += 4; + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "NtTransQuerySecurityDesc[" + super.toString() + + ",fid=0x" + Hexdump.toHexString( fid, 4 ) + + ",securityInformation=0x" + Hexdump.toHexString( securityInformation, 8 ) + "]" ); + } +} diff --git a/src/jcifs/smb/NtTransQuerySecurityDescResponse.java b/src/jcifs/smb/NtTransQuerySecurityDescResponse.java new file mode 100644 index 0000000..fd0f783 --- /dev/null +++ b/src/jcifs/smb/NtTransQuerySecurityDescResponse.java @@ -0,0 +1,66 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.IOException; + +class NtTransQuerySecurityDescResponse extends SmbComNtTransactionResponse { + + SecurityDescriptor securityDescriptor; + + NtTransQuerySecurityDescResponse() { + super(); + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + length = readInt4( buffer, bufferIndex ); + return 4; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + + if (errorCode != 0) + return 4; + + try { + securityDescriptor = new SecurityDescriptor(); + bufferIndex += securityDescriptor.decode(buffer, bufferIndex, len); + } catch (IOException ioe) { + throw new RuntimeException(ioe.getMessage()); + } + + return bufferIndex - start; + } + public String toString() { + return new String( "NtTransQuerySecurityResponse[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/NtlmAuthenticator.java b/src/jcifs/smb/NtlmAuthenticator.java new file mode 100644 index 0000000..c0d77f7 --- /dev/null +++ b/src/jcifs/smb/NtlmAuthenticator.java @@ -0,0 +1,77 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +/** +This class can be extended by applications that wish to trap authentication related exceptions and automatically retry the exceptional operation with different credentials. Read jCIFS Exceptions and NtlmAuthenticator for complete details. + */ + +public abstract class NtlmAuthenticator { + + private static NtlmAuthenticator auth; + + private String url; + private SmbAuthException sae; + + private void reset() { + url = null; + sae = null; + } + +/** +Set the default NtlmAuthenticator. Once the default authenticator is set it cannot be changed. Calling this metho again will have no effect. + */ + + public synchronized static void setDefault( NtlmAuthenticator a ) { + if( auth != null ) { + return; + } + auth = a; + } + + protected final String getRequestingURL() { + return url; + } + protected final SmbAuthException getRequestingException() { + return sae; + } + +/** +Used internally by jCIFS when an SmbAuthException is trapped to retrieve new user credentials. + */ + + public static NtlmPasswordAuthentication + requestNtlmPasswordAuthentication( String url, SmbAuthException sae ) { + if( auth == null ) { + return null; + } + synchronized( auth ) { + auth.url = url; + auth.sae = sae; + return auth.getNtlmPasswordAuthentication(); + } + } +/** +An application extending this class must provide an implementation for this method that returns new user credentials try try when accessing SMB resources described by the getRequestingURL and getRequestingException methods. +If this method returns null the SmbAuthException that triggered the authenticator check will simply be rethrown. The default implementation returns null. +*/ + protected NtlmPasswordAuthentication getNtlmPasswordAuthentication() { + return null; + } +} diff --git a/src/jcifs/smb/NtlmChallenge.java b/src/jcifs/smb/NtlmChallenge.java new file mode 100644 index 0000000..753b8a4 --- /dev/null +++ b/src/jcifs/smb/NtlmChallenge.java @@ -0,0 +1,40 @@ +/* jcifs smb client library in Java + * Copyright (C) 2004 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.Serializable; +import jcifs.UniAddress; +import jcifs.util.Hexdump; + +public final class NtlmChallenge implements Serializable { + + public byte[] challenge; + public UniAddress dc; + + NtlmChallenge( byte[] challenge, UniAddress dc ) { + this.challenge = challenge; + this.dc = dc; + } + + public String toString() { + return "NtlmChallenge[challenge=0x" + + Hexdump.toHexString( challenge, 0, challenge.length * 2 ) + + ",dc=" + dc.toString() + "]"; + } +} diff --git a/src/jcifs/smb/NtlmContext.java b/src/jcifs/smb/NtlmContext.java new file mode 100644 index 0000000..f431397 --- /dev/null +++ b/src/jcifs/smb/NtlmContext.java @@ -0,0 +1,177 @@ +/* jcifs smb client library in Java + * Copyright (C) 2008 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.IOException; +import java.security.*; +import jcifs.ntlmssp.*; +import jcifs.util.LogStream; +import jcifs.util.Hexdump; +import jcifs.util.Encdec; + +/** +For initiating NTLM authentication (including NTLMv2). If you want to add NTLMv2 authentication support to something this is what you want to use. See the code for details. Note that JCIFS does not implement the acceptor side of NTLM authentication. + */ + +public class NtlmContext { + + + NtlmPasswordAuthentication auth; + int ntlmsspFlags; + String workstation; + boolean isEstablished = false; + byte[] serverChallenge = null; + byte[] signingKey = null; + String netbiosName = null; + int state = 1; + LogStream log; + + public NtlmContext(NtlmPasswordAuthentication auth, boolean doSigning) { + this.auth = auth; + this.ntlmsspFlags = ntlmsspFlags | + NtlmFlags.NTLMSSP_REQUEST_TARGET | + NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2 | + NtlmFlags.NTLMSSP_NEGOTIATE_128; + if (doSigning) { + this.ntlmsspFlags |= NtlmFlags.NTLMSSP_NEGOTIATE_SIGN | + NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN | + NtlmFlags.NTLMSSP_NEGOTIATE_KEY_EXCH; + } + this.workstation = Type1Message.getDefaultWorkstation(); + log = LogStream.getInstance(); + } + + public String toString() { + String ret = "NtlmContext[auth=" + auth + + ",ntlmsspFlags=0x" + Hexdump.toHexString(ntlmsspFlags, 8) + + ",workstation=" + workstation + + ",isEstablished=" + isEstablished + + ",state=" + state + + ",serverChallenge="; + if (serverChallenge == null) { + ret += "null"; + } else { + ret += Hexdump.toHexString(serverChallenge, 0, serverChallenge.length * 2); + } + ret += ",signingKey="; + if (signingKey == null) { + ret += "null"; + } else { + ret += Hexdump.toHexString(signingKey, 0, signingKey.length * 2); + } + ret += "]"; + return ret; + } + + public boolean isEstablished() { + return isEstablished; + } + public byte[] getServerChallenge() + { + return serverChallenge; + } + public byte[] getSigningKey() + { + return signingKey; + } + public String getNetbiosName() + { + return netbiosName; + } + + private String getNtlmsspListItem(byte[] type2token, int id0) + { + int ri = 58; + + for ( ;; ) { + int id = Encdec.dec_uint16le(type2token, ri); + int len = Encdec.dec_uint16le(type2token, ri + 2); + ri += 4; + if (id == 0 || (ri + len) > type2token.length) { + break; + } else if (id == id0) { + try { + return new String(type2token, ri, len, SmbConstants.UNI_ENCODING); + } catch (java.io.UnsupportedEncodingException uee) { + break; + } + } + ri += len; + } + + return null; + } + public byte[] initSecContext(byte[] token, int offset, int len) throws SmbException { + switch (state) { + case 1: + Type1Message msg1 = new Type1Message(ntlmsspFlags, auth.getDomain(), workstation); + token = msg1.toByteArray(); + + if (log.level >= 4) { + log.println(msg1); + if (log.level >= 6) + Hexdump.hexdump(log, token, 0, token.length); + } + + state++; + break; + case 2: + try { + Type2Message msg2 = new Type2Message(token); + + if (log.level >= 4) { + log.println(msg2); + if (log.level >= 6) + Hexdump.hexdump(log, token, 0, token.length); + } + + serverChallenge = msg2.getChallenge(); + ntlmsspFlags &= msg2.getFlags(); + +// netbiosName = getNtlmsspListItem(token, 0x0001); + + Type3Message msg3 = new Type3Message(msg2, + auth.getPassword(), + auth.getDomain(), + auth.getUsername(), + workstation, + ntlmsspFlags); + token = msg3.toByteArray(); + + if (log.level >= 4) { + log.println(msg3); + if (log.level >= 6) + Hexdump.hexdump(log, token, 0, token.length); + } + + if ((ntlmsspFlags & NtlmFlags.NTLMSSP_NEGOTIATE_SIGN) != 0) + signingKey = msg3.getMasterKey(); + + isEstablished = true; + state++; + break; + } catch (Exception e) { + throw new SmbException(e.getMessage(), e); + } + default: + throw new SmbException("Invalid state"); + } + return token; + } +} diff --git a/src/jcifs/smb/NtlmPasswordAuthentication.java b/src/jcifs/smb/NtlmPasswordAuthentication.java new file mode 100644 index 0000000..b6be290 --- /dev/null +++ b/src/jcifs/smb/NtlmPasswordAuthentication.java @@ -0,0 +1,630 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.UnsupportedEncodingException; +import java.io.Serializable; +import java.security.Principal; +import java.security.MessageDigest; +import java.security.GeneralSecurityException; +import java.util.Random; +import java.util.Arrays; +import jcifs.Config; +import jcifs.util.*; + +/** + * This class stores and encrypts NTLM user credentials. The default + * credentials are retrieved from the jcifs.smb.client.domain, + * jcifs.smb.client.username, and jcifs.smb.client.password + * properties. + *

+ * Read jCIFS Exceptions and + * NtlmAuthenticator for related information. + */ + +public final class NtlmPasswordAuthentication implements Principal, Serializable { + + private static final int LM_COMPATIBILITY = + Config.getInt("jcifs.smb.lmCompatibility", 3); + + private static final Random RANDOM = new Random(); + + private static LogStream log = LogStream.getInstance(); + + // KGS!@#$% + private static final byte[] S8 = { + (byte)0x4b, (byte)0x47, (byte)0x53, (byte)0x21, + (byte)0x40, (byte)0x23, (byte)0x24, (byte)0x25 + }; + /* Accepts key multiple of 7 + * Returns enc multiple of 8 + * Multiple is the same like: 21 byte key gives 24 byte result + */ + private static void E( byte[] key, byte[] data, byte[] e ) { + byte[] key7 = new byte[7]; + byte[] e8 = new byte[8]; + + for( int i = 0; i < key.length / 7; i++ ) { + System.arraycopy( key, i * 7, key7, 0, 7 ); + DES des = new DES( key7 ); + des.encrypt( data, e8 ); + System.arraycopy( e8, 0, e, i * 8, 8 ); + } + } + + static String DEFAULT_DOMAIN; + static String DEFAULT_USERNAME; + static String DEFAULT_PASSWORD; + static final String BLANK = ""; + + public static final NtlmPasswordAuthentication ANONYMOUS = new NtlmPasswordAuthentication("", "", ""); + + static void initDefaults() { + if (DEFAULT_DOMAIN != null) return; + DEFAULT_DOMAIN = Config.getProperty("jcifs.smb.client.domain", "?"); + DEFAULT_USERNAME = Config.getProperty("jcifs.smb.client.username", "GUEST"); + DEFAULT_PASSWORD = Config.getProperty("jcifs.smb.client.password", BLANK); + } + +/** + * Generate the ANSI DES hash for the password associated with these credentials. + */ + static public byte[] getPreNTLMResponse( String password, byte[] challenge ) { + byte[] p14 = new byte[14]; + byte[] p21 = new byte[21]; + byte[] p24 = new byte[24]; + byte[] passwordBytes; + try { + passwordBytes = password.toUpperCase().getBytes( ServerMessageBlock.OEM_ENCODING ); + } catch( UnsupportedEncodingException uee ) { + throw new RuntimeException("Try setting jcifs.encoding=US-ASCII", uee); + } + int passwordLength = passwordBytes.length; + + // Only encrypt the first 14 bytes of the password for Pre 0.12 NT LM + if( passwordLength > 14) { + passwordLength = 14; + } + System.arraycopy( passwordBytes, 0, p14, 0, passwordLength ); + E( p14, S8, p21); + E( p21, challenge, p24); + return p24; + } +/** + * Generate the Unicode MD4 hash for the password associated with these credentials. + */ + static public byte[] getNTLMResponse( String password, byte[] challenge ) { + byte[] uni = null; + byte[] p21 = new byte[21]; + byte[] p24 = new byte[24]; + + try { + uni = password.getBytes( SmbConstants.UNI_ENCODING ); + } catch( UnsupportedEncodingException uee ) { + if( log.level > 0 ) + uee.printStackTrace( log ); + } + MD4 md4 = new MD4(); + md4.update( uni ); + try { + md4.digest(p21, 0, 16); + } catch (Exception ex) { + if( log.level > 0 ) + ex.printStackTrace( log ); + } + E( p21, challenge, p24 ); + return p24; + } + + /** + * Creates the LMv2 response for the supplied information. + * + * @param domain The domain in which the username exists. + * @param user The username. + * @param password The user's password. + * @param challenge The server challenge. + * @param clientChallenge The client challenge (nonce). + */ + public static byte[] getLMv2Response(String domain, String user, + String password, byte[] challenge, byte[] clientChallenge) { + try { + byte[] hash = new byte[16]; + byte[] response = new byte[24]; +// The next 2-1/2 lines of this should be placed with nTOWFv1 in place of password + MD4 md4 = new MD4(); + md4.update(password.getBytes(SmbConstants.UNI_ENCODING)); + HMACT64 hmac = new HMACT64(md4.digest()); + hmac.update(user.toUpperCase().getBytes(SmbConstants.UNI_ENCODING)); + hmac.update(domain.toUpperCase().getBytes(SmbConstants.UNI_ENCODING)); + hmac = new HMACT64(hmac.digest()); + hmac.update(challenge); + hmac.update(clientChallenge); + hmac.digest(response, 0, 16); + System.arraycopy(clientChallenge, 0, response, 16, 8); + return response; + } catch (Exception ex) { + if( log.level > 0 ) + ex.printStackTrace( log ); + return null; + } + } + public static byte[] getNTLM2Response(byte[] nTOWFv1, + byte[] serverChallenge, + byte[] clientChallenge) + { + byte[] sessionHash = new byte[8]; + + try { + MessageDigest md5; + md5 = MessageDigest.getInstance("MD5"); + md5.update(serverChallenge); + md5.update(clientChallenge, 0, 8); + System.arraycopy(md5.digest(), 0, sessionHash, 0, 8); + } catch (GeneralSecurityException gse) { + if (log.level > 0) + gse.printStackTrace(log); + throw new RuntimeException("MD5", gse); + } + + byte[] key = new byte[21]; + System.arraycopy(nTOWFv1, 0, key, 0, 16); + byte[] ntResponse = new byte[24]; + E(key, sessionHash, ntResponse); + + return ntResponse; + } + public static byte[] nTOWFv1(String password) + { + try { + MD4 md4 = new MD4(); + md4.update(password.getBytes(SmbConstants.UNI_ENCODING)); + return md4.digest(); + } catch (UnsupportedEncodingException uee) { + throw new RuntimeException(uee.getMessage()); + } + } + public static byte[] nTOWFv2(String domain, String username, String password) + { + try { + MD4 md4 = new MD4(); + md4.update(password.getBytes(SmbConstants.UNI_ENCODING)); + HMACT64 hmac = new HMACT64(md4.digest()); + hmac.update(username.toUpperCase().getBytes(SmbConstants.UNI_ENCODING)); + hmac.update(domain.getBytes(SmbConstants.UNI_ENCODING)); + return hmac.digest(); + } catch (UnsupportedEncodingException uee) { + throw new RuntimeException(uee.getMessage()); + } + } + static byte[] computeResponse(byte[] responseKey, + byte[] serverChallenge, + byte[] clientData, + int offset, + int length) + { + HMACT64 hmac = new HMACT64(responseKey); + hmac.update(serverChallenge); + hmac.update(clientData, offset, length); + byte[] mac = hmac.digest(); + byte[] ret = new byte[mac.length + clientData.length]; + System.arraycopy(mac, 0, ret, 0, mac.length); + System.arraycopy(clientData, 0, ret, mac.length, clientData.length); + return ret; + } + public static byte[] getLMv2Response( + byte[] responseKeyLM, + byte[] serverChallenge, + byte[] clientChallenge) + { + return NtlmPasswordAuthentication.computeResponse(responseKeyLM, + serverChallenge, + clientChallenge, + 0, + clientChallenge.length); + } + public static byte[] getNTLMv2Response( + byte[] responseKeyNT, + byte[] serverChallenge, + byte[] clientChallenge, + long nanos1601, + byte[] targetInfo) + { + int targetInfoLength = targetInfo != null ? targetInfo.length : 0; + byte[] temp = new byte[28 + targetInfoLength + 4]; + + Encdec.enc_uint32le(0x00000101, temp, 0); // Header + Encdec.enc_uint32le(0x00000000, temp, 4); // Reserved + Encdec.enc_uint64le(nanos1601, temp, 8); + System.arraycopy(clientChallenge, 0, temp, 16, 8); + Encdec.enc_uint32le(0x00000000, temp, 24); // Unknown + if (targetInfo != null) + System.arraycopy(targetInfo, 0, temp, 28, targetInfoLength); + Encdec.enc_uint32le(0x00000000, temp, 28 + targetInfoLength); // mystery bytes! + + return NtlmPasswordAuthentication.computeResponse(responseKeyNT, + serverChallenge, + temp, + 0, + temp.length); + } + + static final NtlmPasswordAuthentication NULL = + new NtlmPasswordAuthentication( "", "", "" ); + static final NtlmPasswordAuthentication GUEST = + new NtlmPasswordAuthentication( "?", "GUEST", "" ); + static final NtlmPasswordAuthentication DEFAULT = + new NtlmPasswordAuthentication( null ); + + String domain; + String username; + String password; + byte[] ansiHash; + byte[] unicodeHash; + boolean hashesExternal = false; + byte[] clientChallenge = null; + byte[] challenge = null; + +/** + * Create an NtlmPasswordAuthentication object from the userinfo + * component of an SMB URL like "domain;user:pass". This constructor + * is used internally be jCIFS when parsing SMB URLs. + */ + + public NtlmPasswordAuthentication( String userInfo ) { + domain = username = password = null; + + if( userInfo != null ) { + try { + userInfo = unescape( userInfo ); + } catch( UnsupportedEncodingException uee ) { + } + int i, u, end; + char c; + + end = userInfo.length(); + for( i = 0, u = 0; i < end; i++ ) { + c = userInfo.charAt( i ); + if( c == ';' ) { + domain = userInfo.substring( 0, i ); + u = i + 1; + } else if( c == ':' ) { + password = userInfo.substring( i + 1 ); + break; + } + } + username = userInfo.substring( u, i ); + } + + initDefaults(); + + if( domain == null ) this.domain = DEFAULT_DOMAIN; + if( username == null ) this.username = DEFAULT_USERNAME; + if( password == null ) this.password = DEFAULT_PASSWORD; + } +/** + * Create an NtlmPasswordAuthentication object from a + * domain, username, and password. Parameters that are null + * will be substituted with jcifs.smb.client.domain, + * jcifs.smb.client.username, jcifs.smb.client.password + * property values. + */ + public NtlmPasswordAuthentication( String domain, String username, String password ) { + int ci; + + ci = username.indexOf('@'); + if (ci > 0) { + domain = username.substring(ci + 1); + username = username.substring(0, ci); + } else { + ci = username.indexOf('\\'); + if (ci > 0) { + domain = username.substring(0, ci); + username = username.substring(ci + 1); + } + } + + this.domain = domain; + this.username = username; + this.password = password; + + initDefaults(); + + if( domain == null ) this.domain = DEFAULT_DOMAIN; + if( username == null ) this.username = DEFAULT_USERNAME; + if( password == null ) this.password = DEFAULT_PASSWORD; + } +/** + * Create an NtlmPasswordAuthentication object with raw password + * hashes. This is used exclusively by the jcifs.http.NtlmSsp + * class which is in turn used by NTLM HTTP authentication functionality. + */ + public NtlmPasswordAuthentication( String domain, String username, + byte[] challenge, byte[] ansiHash, byte[] unicodeHash ) { + if( domain == null || username == null || + ansiHash == null || unicodeHash == null ) { + throw new IllegalArgumentException( "External credentials cannot be null" ); + } + this.domain = domain; + this.username = username; + this.password = null; + this.challenge = challenge; + this.ansiHash = ansiHash; + this.unicodeHash = unicodeHash; + hashesExternal = true; + } + +/** + * Returns the domain. + */ + public String getDomain() { + return domain; + } + +/** + * Returns the username. + */ + public String getUsername() { + return username; + } +/** + * Returns the password in plain text or null if the raw password + * hashes were used to construct this NtlmPasswordAuthentication + * object which will be the case when NTLM HTTP Authentication is + * used. There is no way to retrieve a users password in plain text unless + * it is supplied by the user at runtime. + */ + public String getPassword() { + return password; + } +/** + * Return the domain and username in the format: + * domain\\username. This is equivalent to toString(). + */ + public String getName() { + boolean d = domain.length() > 0 && domain.equals( "?" ) == false; + return d ? domain + "\\" + username : username; + } + +/** + * Computes the 24 byte ANSI password hash given the 8 byte server challenge. + */ + public byte[] getAnsiHash( byte[] challenge ) { + if( hashesExternal ) { + return ansiHash; + } + switch (LM_COMPATIBILITY) { + case 0: + case 1: + return getPreNTLMResponse( password, challenge ); + case 2: + return getNTLMResponse( password, challenge ); + case 3: + case 4: + case 5: + if( clientChallenge == null ) { + clientChallenge = new byte[8]; + RANDOM.nextBytes( clientChallenge ); + } + return getLMv2Response(domain, username, password, challenge, + clientChallenge); + default: + return getPreNTLMResponse( password, challenge ); + } + } +/** + * Computes the 24 byte Unicode password hash given the 8 byte server challenge. + */ + public byte[] getUnicodeHash( byte[] challenge ) { + if( hashesExternal ) { + return unicodeHash; + } + switch (LM_COMPATIBILITY) { + case 0: + case 1: + case 2: + return getNTLMResponse( password, challenge ); + case 3: + case 4: + case 5: + /* + if( clientChallenge == null ) { + clientChallenge = new byte[8]; + RANDOM.nextBytes( clientChallenge ); + } + return getNTLMv2Response(domain, username, password, null, + challenge, clientChallenge); + */ + return new byte[0]; + default: + return getNTLMResponse( password, challenge ); + } + } + + public byte[] getSigningKey(byte[] challenge) throws SmbException + { + switch (LM_COMPATIBILITY) { + case 0: + case 1: + case 2: + byte[] signingKey = new byte[40]; + getUserSessionKey(challenge, signingKey, 0); + System.arraycopy(getUnicodeHash(challenge), 0, signingKey, 16, 24); + return signingKey; + case 3: + case 4: + case 5: + /* This code is only called if extended security is not on. This will + * all be cleaned up an normalized in JCIFS 2.x. + */ + throw new SmbException("NTLMv2 requires extended security (jcifs.smb.client.useExtendedSecurity must be true if jcifs.smb.lmCompatibility >= 3)"); + } + return null; + } + + /** + * Returns the effective user session key. + * + * @param challenge The server challenge. + * @return A byte[] containing the effective user session key, + * used in SMB MAC signing and NTLMSSP signing and sealing. + */ + public byte[] getUserSessionKey(byte[] challenge) { + if (hashesExternal) return null; + byte[] key = new byte[16]; + try { + getUserSessionKey(challenge, key, 0); + } catch (Exception ex) { + if( log.level > 0 ) + ex.printStackTrace( log ); + } + return key; + } + + /** + * Calculates the effective user session key. + * + * @param challenge The server challenge. + * @param dest The destination array in which the user session key will be + * placed. + * @param offset The offset in the destination array at which the + * session key will start. + */ + void getUserSessionKey(byte[] challenge, byte[] dest, int offset) throws SmbException { + if (hashesExternal) return; + try { + MD4 md4 = new MD4(); + md4.update(password.getBytes(SmbConstants.UNI_ENCODING)); + switch (LM_COMPATIBILITY) { + case 0: + case 1: + case 2: + md4.update(md4.digest()); + md4.digest(dest, offset, 16); + break; + case 3: + case 4: + case 5: + if( clientChallenge == null ) { + clientChallenge = new byte[8]; + RANDOM.nextBytes( clientChallenge ); + } + + HMACT64 hmac = new HMACT64(md4.digest()); + hmac.update(username.toUpperCase().getBytes( + SmbConstants.UNI_ENCODING)); + hmac.update(domain.toUpperCase().getBytes( + SmbConstants.UNI_ENCODING)); + byte[] ntlmv2Hash = hmac.digest(); + hmac = new HMACT64(ntlmv2Hash); + hmac.update(challenge); + hmac.update(clientChallenge); + HMACT64 userKey = new HMACT64(ntlmv2Hash); + userKey.update(hmac.digest()); + userKey.digest(dest, offset, 16); + break; + default: + md4.update(md4.digest()); + md4.digest(dest, offset, 16); + break; + } + } catch (Exception e) { + throw new SmbException("", e); + } + } + +/** + * Compares two NtlmPasswordAuthentication objects for + * equality. Two NtlmPasswordAuthentication objects are equal if + * their caseless domain and username fields are equal and either both hashes are external and they are equal or both internally supplied passwords are equal. If one NtlmPasswordAuthentication object has external hashes (meaning negotiated via NTLM HTTP Authentication) and the other does not they will not be equal. This is technically not correct however the server 8 byte challage would be required to compute and compare the password hashes but that it not available with this method. + */ + public boolean equals( Object obj ) { + if( obj instanceof NtlmPasswordAuthentication ) { + NtlmPasswordAuthentication ntlm = (NtlmPasswordAuthentication)obj; + if( ntlm.domain.toUpperCase().equals( domain.toUpperCase() ) && + ntlm.username.toUpperCase().equals( username.toUpperCase() )) { + if( hashesExternal && ntlm.hashesExternal ) { + return Arrays.equals( ansiHash, ntlm.ansiHash ) && + Arrays.equals( unicodeHash, ntlm.unicodeHash ); + /* This still isn't quite right. If one npa object does not have external + * hashes and the other does then they will not be considered equal even + * though they may be. + */ + } else if( !hashesExternal && password.equals( ntlm.password )) { + return true; + } + } + } + return false; + } + + +/** + * Return the upcased username hash code. + */ + public int hashCode() { + return getName().toUpperCase().hashCode(); + } +/** + * Return the domain and username in the format: + * domain\\username. This is equivalent to getName(). + */ + public String toString() { + return getName(); + } + + static String unescape( String str ) throws NumberFormatException, UnsupportedEncodingException { + char ch; + int i, j, state, len; + char[] out; + byte[] b = new byte[1]; + + if( str == null ) { + return null; + } + + len = str.length(); + out = new char[len]; + state = 0; + for( i = j = 0; i < len; i++ ) { + switch( state ) { + case 0: + ch = str.charAt( i ); + if( ch == '%' ) { + state = 1; + } else { + out[j++] = ch; + } + break; + case 1: + /* Get ASCII hex value and convert to platform dependant + * encoding like EBCDIC perhaps + */ + b[0] = (byte)(Integer.parseInt( str.substring( i, i + 2 ), 16 ) & 0xFF); + out[j++] = (new String( b, 0, 1, "ASCII" )).charAt( 0 ); + i++; + state = 0; + } + } + + return new String( out, 0, j ); + } + +} + diff --git a/src/jcifs/smb/SID.java b/src/jcifs/smb/SID.java new file mode 100644 index 0000000..4d3df48 --- /dev/null +++ b/src/jcifs/smb/SID.java @@ -0,0 +1,713 @@ +/* jcifs smb client library in Java + * Copyright (C) 2006 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.*; +import java.io.IOException; + +import jcifs.util.Hexdump; +import jcifs.dcerpc.*; +import jcifs.dcerpc.msrpc.*; + +/** + * A Windows SID is a numeric identifier used to represent Windows + * accounts. SIDs are commonly represented using a textual format such as + * S-1-5-21-1496946806-2192648263-3843101252-1029 but they may + * also be resolved to yield the name of the associated Windows account + * such as Administrators or MYDOM\alice. + *

+ * Consider the following output of examples/SidLookup.java: + *

+ *        toString: S-1-5-21-4133388617-793952518-2001621813-512
+ * toDisplayString: WNET\Domain Admins
+ *         getType: 2
+ *     getTypeText: Domain group
+ *   getDomainName: WNET
+ *  getAccountName: Domain Admins
+ * 
+ */ + +public class SID extends rpc.sid_t { + + public static final int SID_TYPE_USE_NONE = lsarpc.SID_NAME_USE_NONE; + public static final int SID_TYPE_USER = lsarpc.SID_NAME_USER; + public static final int SID_TYPE_DOM_GRP = lsarpc.SID_NAME_DOM_GRP; + public static final int SID_TYPE_DOMAIN = lsarpc.SID_NAME_DOMAIN; + public static final int SID_TYPE_ALIAS = lsarpc.SID_NAME_ALIAS; + public static final int SID_TYPE_WKN_GRP = lsarpc.SID_NAME_WKN_GRP; + public static final int SID_TYPE_DELETED = lsarpc.SID_NAME_DELETED; + public static final int SID_TYPE_INVALID = lsarpc.SID_NAME_INVALID; + public static final int SID_TYPE_UNKNOWN = lsarpc.SID_NAME_UNKNOWN; + + static final String[] SID_TYPE_NAMES = { + "0", + "User", + "Domain group", + "Domain", + "Local group", + "Builtin group", + "Deleted", + "Invalid", + "Unknown" + }; + + public static final int SID_FLAG_RESOLVE_SIDS = 0x0001; + + public static SID EVERYONE = null; + public static SID CREATOR_OWNER = null; + public static SID SYSTEM = null; + + static { + try { + EVERYONE = new SID("S-1-1-0"); + CREATOR_OWNER = new SID("S-1-3-0"); + SYSTEM = new SID("S-1-5-18"); + } catch (SmbException se) { + } + } + + static Map sid_cache = Collections.synchronizedMap(new HashMap()); + + static void resolveSids(DcerpcHandle handle, + LsaPolicyHandle policyHandle, + SID[] sids) throws IOException { + MsrpcLookupSids rpc = new MsrpcLookupSids(policyHandle, sids); + handle.sendrecv(rpc); + switch (rpc.retval) { + case 0: + case NtStatus.NT_STATUS_NONE_MAPPED: + case 0x00000107: // NT_STATUS_SOME_NOT_MAPPED + break; + default: + throw new SmbException(rpc.retval, false); + } + + for (int si = 0; si < sids.length; si++) { + sids[si].type = rpc.names.names[si].sid_type; + sids[si].domainName = null; + + switch (sids[si].type) { + case SID_TYPE_USER: + case SID_TYPE_DOM_GRP: + case SID_TYPE_DOMAIN: + case SID_TYPE_ALIAS: + case SID_TYPE_WKN_GRP: + int sid_index = rpc.names.names[si].sid_index; + rpc.unicode_string ustr = rpc.domains.domains[sid_index].name; + sids[si].domainName = (new UnicodeString(ustr, false)).toString(); + break; + } + + sids[si].acctName = (new UnicodeString(rpc.names.names[si].name, false)).toString(); + sids[si].origin_server = null; + sids[si].origin_auth = null; + } + } + static void resolveSids0(String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids) throws IOException { + DcerpcHandle handle = null; + LsaPolicyHandle policyHandle = null; + + try { + handle = DcerpcHandle.getHandle("ncacn_np:" + authorityServerName + + "[\\PIPE\\lsarpc]", auth); + String server = authorityServerName; + int dot = server.indexOf('.'); + if (dot > 0 && Character.isDigit(server.charAt(0)) == false) + server = server.substring(0, dot); + policyHandle = new LsaPolicyHandle(handle, "\\\\" + server, 0x00000800); + SID.resolveSids(handle, policyHandle, sids); + } finally { + if (handle != null) { + if (policyHandle != null) { + policyHandle.close(); + } + handle.close(); + } + } + } + + static public void resolveSids(String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids, + int offset, + int length) throws IOException { + ArrayList list = new ArrayList(sids.length); + int si; + + for (si = 0; si < length; si++) { + SID sid = (SID)sid_cache.get(sids[offset + si]); + if (sid != null) { + sids[offset + si].type = sid.type; + sids[offset + si].domainName = sid.domainName; + sids[offset + si].acctName = sid.acctName; + } else { + list.add(sids[offset + si]); + } + } + + if (list.size() > 0) { + sids = (SID[])list.toArray(new SID[0]); + SID.resolveSids0(authorityServerName, auth, sids); + for (si = 0; si < sids.length; si++) { + sid_cache.put(sids[si], sids[si]); + } + } + } + /** + * Resolve an array of SIDs using a cache and at most one MSRPC request. + *

+ * This method will attempt + * to resolve SIDs using a cache and cache the results of any SIDs that + * required resolving with the authority. SID cache entries are currently not + * expired because under normal circumstances SID information never changes. + * + * @param authorityServerName The hostname of the server that should be queried. For maximum efficiency this should be the hostname of a domain controller however a member server will work as well and a domain controller may not return names for SIDs corresponding to local accounts for which the domain controller is not an authority. + * @param auth The credentials that should be used to communicate with the named server. As usual, null indicates that default credentials should be used. + * @param sids The SIDs that should be resolved. After this function is called, the names associated with the SIDs may be queried with the toDisplayString, getDomainName, and getAccountName methods. + */ + static public void resolveSids(String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids) throws IOException { + ArrayList list = new ArrayList(sids.length); + int si; + + for (si = 0; si < sids.length; si++) { + SID sid = (SID)sid_cache.get(sids[si]); + if (sid != null) { + sids[si].type = sid.type; + sids[si].domainName = sid.domainName; + sids[si].acctName = sid.acctName; + } else { + list.add(sids[si]); + } + } + + if (list.size() > 0) { + sids = (SID[])list.toArray(new SID[0]); + SID.resolveSids0(authorityServerName, auth, sids); + for (si = 0; si < sids.length; si++) { + sid_cache.put(sids[si], sids[si]); + } + } + } + public static SID getServerSid(String server, + NtlmPasswordAuthentication auth) throws IOException { + DcerpcHandle handle = null; + LsaPolicyHandle policyHandle = null; + lsarpc.LsarDomainInfo info = new lsarpc.LsarDomainInfo(); + MsrpcQueryInformationPolicy rpc; + + try { + handle = DcerpcHandle.getHandle("ncacn_np:" + server + + "[\\PIPE\\lsarpc]", auth); + // NetApp doesn't like the 'generic' access mask values + policyHandle = new LsaPolicyHandle(handle, null, 0x00000001); + rpc = new MsrpcQueryInformationPolicy(policyHandle, + (short)lsarpc.POLICY_INFO_ACCOUNT_DOMAIN, + info); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + + return new SID(info.sid, + SID.SID_TYPE_DOMAIN, + (new UnicodeString(info.name, false)).toString(), + null, + false); + } finally { + if (handle != null) { + if (policyHandle != null) { + policyHandle.close(); + } + handle.close(); + } + } + } + public static byte[] toByteArray(rpc.sid_t sid) { + byte[] dst = new byte[1 + 1 + 6 + sid.sub_authority_count * 4]; + int di = 0; + dst[di++] = sid.revision; + dst[di++] = sid.sub_authority_count; + System.arraycopy(sid.identifier_authority, 0, dst, di, 6); + di += 6; + for (int ii = 0; ii < sid.sub_authority_count; ii++) { + jcifs.util.Encdec.enc_uint32le(sid.sub_authority[ii], dst, di); + di += 4; + } + return dst; + } + + int type; + String domainName = null; + String acctName = null; + String origin_server = null; + NtlmPasswordAuthentication origin_auth = null; + + /* + * Construct a SID from it's binary representation. + */ + public SID(byte[] src, int si) { + revision = src[si++]; + sub_authority_count = src[si++]; + identifier_authority = new byte[6]; + System.arraycopy(src, si, identifier_authority, 0, 6); + si += 6; + if (sub_authority_count > 100) + throw new RuntimeException( "Invalid SID sub_authority_count" ); + sub_authority = new int[sub_authority_count]; + for (int i = 0; i < sub_authority_count; i++) { + sub_authority[i] = ServerMessageBlock.readInt4( src, si ); + si += 4; + } + } + /** + * Construct a SID from it's textual representation such as + * S-1-5-21-1496946806-2192648263-3843101252-1029. + */ + public SID(String textual) throws SmbException { + StringTokenizer st = new StringTokenizer(textual, "-"); + if (st.countTokens() < 3 || !st.nextToken().equals("S")) + // need S-N-M + throw new SmbException("Bad textual SID format: " + textual); + + this.revision = Byte.parseByte(st.nextToken()); + String tmp = st.nextToken(); + long id = 0; + if (tmp.startsWith("0x")) + id = Long.parseLong(tmp.substring(2), 16); + else + id = Long.parseLong(tmp); + + this.identifier_authority = new byte[6]; + for (int i = 5; id > 0; i--) { + this.identifier_authority[i] = (byte) (id % 256); + id >>= 8; + } + + this.sub_authority_count = (byte) st.countTokens(); + if (this.sub_authority_count > 0) { + this.sub_authority = new int[this.sub_authority_count]; + for (int i = 0; i < this.sub_authority_count; i++) + this.sub_authority[i] = (int)(Long.parseLong(st.nextToken()) & 0xFFFFFFFFL); + } + } + + /** + * Construct a SID from a domain SID and an RID + * (relative identifier). For example, a domain SID + * S-1-5-21-1496946806-2192648263-3843101252 and RID 1029 would + * yield the SID S-1-5-21-1496946806-2192648263-3843101252-1029. + */ + public SID(SID domsid, int rid) { + this.revision = domsid.revision; + this.identifier_authority = domsid.identifier_authority; + this.sub_authority_count = (byte)(domsid.sub_authority_count + 1); + this.sub_authority = new int[this.sub_authority_count]; + int i; + for (i = 0; i < domsid.sub_authority_count; i++) { + this.sub_authority[i] = domsid.sub_authority[i]; + } + this.sub_authority[i] = rid; + } + public SID(rpc.sid_t sid, + int type, + String domainName, + String acctName, + boolean decrementAuthority) { + this.revision = sid.revision; + this.sub_authority_count = sid.sub_authority_count; + this.identifier_authority = sid.identifier_authority; + this.sub_authority = sid.sub_authority; + this.type = type; + this.domainName = domainName; + this.acctName = acctName; + + if (decrementAuthority) { + this.sub_authority_count--; + this.sub_authority = new int[sub_authority_count]; + for (int i = 0; i < this.sub_authority_count; i++) { + this.sub_authority[i] = sid.sub_authority[i]; + } + } + } + + public SID getDomainSid() { + return new SID(this, + SID_TYPE_DOMAIN, + this.domainName, + null, + getType() != SID_TYPE_DOMAIN); + } + public int getRid() { + if (getType() == SID_TYPE_DOMAIN) + throw new IllegalArgumentException("This SID is a domain sid"); + return sub_authority[sub_authority_count - 1]; + } + + /** + * Returns the type of this SID indicating the state or type of account. + *

+ * SID types are described in the following table. + * + * + * + * + * + * + * + * + * + * + * + * + *
TypeName
SID_TYPE_USE_NONE0
SID_TYPE_USERUser
SID_TYPE_DOM_GRPDomain group
SID_TYPE_DOMAINDomain
SID_TYPE_ALIASLocal group
SID_TYPE_WKN_GRPBuiltin group
SID_TYPE_DELETEDDeleted
SID_TYPE_INVALIDInvalid
SID_TYPE_UNKNOWNUnknown
+ *
+ */ + public int getType() { + if (origin_server != null) + resolveWeak(); + return type; + } + + /** + * Return text represeting the SID type suitable for display to + * users. Text includes 'User', 'Domain group', 'Local group', etc. + */ + public String getTypeText() { + if (origin_server != null) + resolveWeak(); + return SID_TYPE_NAMES[type]; + } + + /** + * Return the domain name of this SID unless it could not be + * resolved in which case the numeric representation is returned. + */ + public String getDomainName() { + if (origin_server != null) + resolveWeak(); + if (type == SID_TYPE_UNKNOWN) { + String full = toString(); + return full.substring(0, full.length() - getAccountName().length() - 1); + } + return domainName; + } + + /** + * Return the sAMAccountName of this SID unless it could not + * be resolved in which case the numeric RID is returned. If this + * SID is a domain SID, this method will return an empty String. + */ + public String getAccountName() { + if (origin_server != null) + resolveWeak(); + if (type == SID_TYPE_UNKNOWN) + return "" + sub_authority[sub_authority_count - 1]; + if (type == SID_TYPE_DOMAIN) + return ""; + return acctName; + } + + public int hashCode() { + int hcode = identifier_authority[5]; + for (int i = 0; i < sub_authority_count; i++) { + hcode += 65599 * sub_authority[i]; + } + return hcode; + } + public boolean equals(Object obj) { + if (obj instanceof SID) { + SID sid = (SID)obj; + if (sid == this) + return true; + if (sid.sub_authority_count == sub_authority_count) { + int i = sub_authority_count; + while (i-- > 0) { + if (sid.sub_authority[i] != sub_authority[i]) { + return false; + } + } + for (i = 0; i < 6; i++) { + if (sid.identifier_authority[i] != identifier_authority[i]) { + return false; + } + } + + return sid.revision == revision; + } + } + return false; + } + + /** + * Return the numeric representation of this sid such as + * S-1-5-21-1496946806-2192648263-3843101252-1029. + */ + public String toString() { + String ret = "S-" + (revision & 0xFF) + "-"; + + if (identifier_authority[0] != (byte)0 || identifier_authority[1] != (byte)0) { + ret += "0x"; + ret += Hexdump.toHexString(identifier_authority, 0, 6); + } else { + long shift = 0; + long id = 0; + for (int i = 5; i > 1; i--) { + id += (identifier_authority[i] & 0xFFL) << shift; + shift += 8; + } + ret += id; + } + + for (int i = 0; i < sub_authority_count ; i++) + ret += "-" + (sub_authority[i] & 0xFFFFFFFFL); + + return ret; + } + + /** + * Return a String representing this SID ideal for display to + * users. This method should return the same text that the ACL + * editor in Windows would display. + *

+ * Specifically, if the SID has + * been resolved and it is not a domain SID or builtin account, + * the full DOMAIN\name form of the account will be + * returned (e.g. MYDOM\alice or MYDOM\Domain Users). + * If the SID has been resolved but it is is a domain SID, + * only the domain name will be returned (e.g. MYDOM). + * If the SID has been resolved but it is a builtin account, + * only the name component will be returned (e.g. SYSTEM). + * If the sid cannot be resolved the numeric representation from + * toString() is returned. + */ + public String toDisplayString() { + if (origin_server != null) + resolveWeak(); + if (domainName != null) { + String str; + + if (type == SID_TYPE_DOMAIN) { + str = domainName; + } else if (type == SID_TYPE_WKN_GRP || + domainName.equals("BUILTIN")) { + if (type == SID_TYPE_UNKNOWN) { + str = toString(); + } else { + str = acctName; + } + } else { + str = domainName + "\\" + acctName; + } + + return str; + } + return toString(); + } + + /** + * Manually resolve this SID. Normally SIDs are automatically + * resolved. However, if a SID is constructed explicitly using a SID + * constructor, JCIFS will have no knowledge of the server that created the + * SID and therefore cannot possibly resolve it automatically. In this case, + * this method will be necessary. + * + * @param authorityServerName The FQDN of the server that is an authority for the SID. + * @param auth Credentials suitable for accessing the SID's information. + */ + public void resolve(String authorityServerName, + NtlmPasswordAuthentication auth) throws IOException { + SID[] sids = new SID[1]; + sids[0] = this; + SID.resolveSids(authorityServerName, auth, sids); + } + + void resolveWeak() { + if (origin_server != null) { + try { + resolve(origin_server, origin_auth); + } catch(IOException ioe) { + } finally { + origin_server = null; + origin_auth = null; + } + } + } + + static SID[] getGroupMemberSids0(DcerpcHandle handle, + SamrDomainHandle domainHandle, + SID domsid, + int rid, + int flags) throws IOException { + SamrAliasHandle aliasHandle = null; + lsarpc.LsarSidArray sidarray = new lsarpc.LsarSidArray(); + MsrpcGetMembersInAlias rpc = null; + + try { + aliasHandle = new SamrAliasHandle(handle, domainHandle, 0x0002000c, rid); + rpc = new MsrpcGetMembersInAlias(aliasHandle, sidarray); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + SID[] sids = new SID[rpc.sids.num_sids]; + + String origin_server = handle.getServer(); + NtlmPasswordAuthentication origin_auth = + (NtlmPasswordAuthentication)handle.getPrincipal(); + + for (int i = 0; i < sids.length; i++) { + sids[i] = new SID(rpc.sids.sids[i].sid, + 0, + null, + null, + false); + sids[i].origin_server = origin_server; + sids[i].origin_auth = origin_auth; + } + if (sids.length > 0 && (flags & SID_FLAG_RESOLVE_SIDS) != 0) { + SID.resolveSids(origin_server, origin_auth, sids); + } + return sids; + } finally { + if (aliasHandle != null) { + aliasHandle.close(); + } + } + } + + public SID[] getGroupMemberSids(String authorityServerName, + NtlmPasswordAuthentication auth, + int flags) throws IOException { + if (type != SID_TYPE_DOM_GRP && type != SID_TYPE_ALIAS) + return new SID[0]; + + DcerpcHandle handle = null; + SamrPolicyHandle policyHandle = null; + SamrDomainHandle domainHandle = null; + SID domsid = getDomainSid(); + + try { + handle = DcerpcHandle.getHandle("ncacn_np:" + authorityServerName + + "[\\PIPE\\samr]", auth); + policyHandle = new SamrPolicyHandle(handle, authorityServerName, 0x00000030); + domainHandle = new SamrDomainHandle(handle, policyHandle, 0x00000200, domsid); + return SID.getGroupMemberSids0(handle, + domainHandle, + domsid, + getRid(), + flags); + } finally { + if (handle != null) { + if (policyHandle != null) { + if (domainHandle != null) { + domainHandle.close(); + } + policyHandle.close(); + } + handle.close(); + } + } + } + + /** + * This specialized method returns a Map of users and local groups for the + * target server where keys are SIDs representing an account and each value + * is an ArrayList of SIDs represents the local groups that the account is + * a member of. + *

+ * This method is designed to assist with computing access control for a + * given user when the target object's ACL has local groups. Local groups + * are not listed in a user's group membership (e.g. as represented by the + * tokenGroups constructed attribute retrived via LDAP). + *

+ * Domain groups nested inside a local group are currently not expanded. In + * this case the key (SID) type will be SID_TYPE_DOM_GRP rather than + * SID_TYPE_USER. + * + * @param authorityServerName The server from which the local groups will be queried. + * @param auth The credentials required to query groups and group members. + * @param flags Flags that control the behavior of the operation. When all + * name associated with SIDs will be required, the SID_FLAG_RESOLVE_SIDS + * flag should be used which causes all group member SIDs to be resolved + * together in a single more efficient operation. + */ + static Map getLocalGroupsMap(String authorityServerName, + NtlmPasswordAuthentication auth, + int flags) throws IOException { + SID domsid = SID.getServerSid(authorityServerName, auth); + DcerpcHandle handle = null; + SamrPolicyHandle policyHandle = null; + SamrDomainHandle domainHandle = null; + samr.SamrSamArray sam = new samr.SamrSamArray(); + MsrpcEnumerateAliasesInDomain rpc; + + try { + handle = DcerpcHandle.getHandle("ncacn_np:" + authorityServerName + + "[\\PIPE\\samr]", auth); + policyHandle = new SamrPolicyHandle(handle, authorityServerName, 0x02000000); + domainHandle = new SamrDomainHandle(handle, policyHandle, 0x02000000, domsid); + rpc = new MsrpcEnumerateAliasesInDomain(domainHandle, 0xFFFF, sam); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + + Map map = new HashMap(); + + for (int ei = 0; ei < rpc.sam.count; ei++) { + samr.SamrSamEntry entry = rpc.sam.entries[ei]; + + SID[] mems = SID.getGroupMemberSids0(handle, + domainHandle, + domsid, + entry.idx, + flags); + SID groupSid = new SID(domsid, entry.idx); + groupSid.type = SID_TYPE_ALIAS; + groupSid.domainName = domsid.getDomainName(); + groupSid.acctName = (new UnicodeString(entry.name, false)).toString(); + + for (int mi = 0; mi < mems.length; mi++) { + ArrayList groups = (ArrayList)map.get(mems[mi]); + if (groups == null) { + groups = new ArrayList(); + map.put(mems[mi], groups); + } + if (!groups.contains(groupSid)) + groups.add(groupSid); + } + } + + return map; + } finally { + if (handle != null) { + if (policyHandle != null) { + if (domainHandle != null) { + domainHandle.close(); + } + policyHandle.close(); + } + handle.close(); + } + } + } +} + diff --git a/src/jcifs/smb/SecurityDescriptor.java b/src/jcifs/smb/SecurityDescriptor.java new file mode 100644 index 0000000..e413174 --- /dev/null +++ b/src/jcifs/smb/SecurityDescriptor.java @@ -0,0 +1,83 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.IOException; + +public class SecurityDescriptor { + + public int type; + public ACE[] aces; + + public SecurityDescriptor() { + } + public SecurityDescriptor(byte[] buffer, int bufferIndex, int len) throws IOException { + this.decode(buffer, bufferIndex, len); + } + public int decode(byte[] buffer, int bufferIndex, int len) throws IOException { + int start = bufferIndex; + + bufferIndex++; // revision + bufferIndex++; + type = ServerMessageBlock.readInt2(buffer, bufferIndex); + bufferIndex += 2; + ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to owner sid + bufferIndex += 4; + ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to group sid + bufferIndex += 4; + ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to sacl + bufferIndex += 4; + int daclOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); + + bufferIndex = start + daclOffset; + + bufferIndex++; // revision + bufferIndex++; + int size = ServerMessageBlock.readInt2(buffer, bufferIndex); + bufferIndex += 2; + int numAces = ServerMessageBlock.readInt4(buffer, bufferIndex); + bufferIndex += 4; + + if (numAces > 4096) + throw new IOException( "Invalid SecurityDescriptor" ); + + if (daclOffset != 0) { + aces = new ACE[numAces]; + for (int i = 0; i < numAces; i++) { + aces[i] = new ACE(); + bufferIndex += aces[i].decode(buffer, bufferIndex); + } + } else { + aces = null; + } + + return bufferIndex - start; + } + public String toString() { + String ret = "SecurityDescriptor:\n"; + if (aces != null) { + for (int ai = 0; ai < aces.length; ai++) { + ret += aces[ai].toString() + "\n"; + } + } else { + ret += "NULL"; + } + return ret; + } +} diff --git a/src/jcifs/smb/ServerMessageBlock.java b/src/jcifs/smb/ServerMessageBlock.java new file mode 100644 index 0000000..e9fa7f7 --- /dev/null +++ b/src/jcifs/smb/ServerMessageBlock.java @@ -0,0 +1,536 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.Config; +import java.io.InputStream; +import java.io.PushbackInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Calendar; +import java.util.Date; +import jcifs.util.Hexdump; +import jcifs.util.LogStream; +import jcifs.util.transport.*; + +abstract class ServerMessageBlock extends Response implements Request, SmbConstants { + + static LogStream log = LogStream.getInstance(); + + static final byte[] header = { + (byte)0xFF, (byte)'S', (byte)'M', (byte)'B', + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 + }; + + static void writeInt2( long val, byte[] dst, int dstIndex ) { + dst[dstIndex] = (byte)(val); + dst[++dstIndex] = (byte)(val >> 8); + } + static void writeInt4( long val, byte[] dst, int dstIndex ) { + dst[dstIndex] = (byte)(val); + dst[++dstIndex] = (byte)(val >>= 8); + dst[++dstIndex] = (byte)(val >>= 8); + dst[++dstIndex] = (byte)(val >> 8); + } + static int readInt2( byte[] src, int srcIndex ) { + return ( src[srcIndex] & 0xFF ) + + (( src[srcIndex + 1] & 0xFF ) << 8 ); + } + static int readInt4( byte[] src, int srcIndex ) { + return ( src[srcIndex] & 0xFF ) + + (( src[srcIndex + 1] & 0xFF ) << 8 ) + + (( src[srcIndex + 2] & 0xFF ) << 16 ) + + (( src[srcIndex + 3] & 0xFF ) << 24 ); + } + static long readInt8( byte[] src, int srcIndex ) { + return (readInt4( src, srcIndex ) & 0xFFFFFFFFL) + + ((long)(readInt4( src, srcIndex + 4 )) << 32); + } + static void writeInt8( long val, byte[] dst, int dstIndex ) { + dst[dstIndex] = (byte)(val); + dst[++dstIndex] = (byte)(val >>= 8); + dst[++dstIndex] = (byte)(val >>= 8); + dst[++dstIndex] = (byte)(val >>= 8); + dst[++dstIndex] = (byte)(val >>= 8); + dst[++dstIndex] = (byte)(val >>= 8); + dst[++dstIndex] = (byte)(val >>= 8); + dst[++dstIndex] = (byte)(val >> 8); + } + static long readTime( byte[] src, int srcIndex ) { + int low = readInt4( src, srcIndex ); + int hi = readInt4( src, srcIndex + 4 ); + long t = ((long)hi << 32L ) | (low & 0xFFFFFFFFL); + t = ( t / 10000L - MILLISECONDS_BETWEEN_1970_AND_1601 ); + return t; + } + static void writeTime( long t, byte[] dst, int dstIndex ) { + if( t != 0L ) { + t = (t + MILLISECONDS_BETWEEN_1970_AND_1601) * 10000L; + } + writeInt8( t, dst, dstIndex ); + } + static long readUTime( byte[] buffer, int bufferIndex ) { + return readInt4( buffer, bufferIndex ) * 1000L; + } + static void writeUTime( long t, byte[] dst, int dstIndex ) { + if( t == 0L || t == 0xFFFFFFFFFFFFFFFFL ) { + writeInt4( 0xFFFFFFFF, dst, dstIndex ); + return; + } + synchronized( TZ ) { + if( TZ.inDaylightTime( new Date() )) { + // in DST + if( TZ.inDaylightTime( new Date( t ))) { + // t also in DST so no correction + } else { + // t not in DST so subtract 1 hour + t -= 3600000; + } + } else { + // not in DST + if( TZ.inDaylightTime( new Date( t ))) { + // t is in DST so add 1 hour + t += 3600000; + } else { + // t isn't in DST either + } + } + } + writeInt4( (int)(t / 1000L), dst, dstIndex ); + } + + /* + * These are all the smbs supported by this library. This includes requests + * and well as their responses for each type however the actuall implementations + * of the readXxxWireFormat and writeXxxWireFormat methods may not be in + * place. For example at the time of this writing the readXxxWireFormat + * for requests and the writeXxxWireFormat for responses are not implemented + * and simply return 0. These would need to be completed for a server + * implementation. + */ + + static final byte SMB_COM_CREATE_DIRECTORY = (byte)0x00; + static final byte SMB_COM_DELETE_DIRECTORY = (byte)0x01; + static final byte SMB_COM_CLOSE = (byte)0x04; + static final byte SMB_COM_DELETE = (byte)0x06; + static final byte SMB_COM_RENAME = (byte)0x07; + static final byte SMB_COM_QUERY_INFORMATION = (byte)0x08; + static final byte SMB_COM_WRITE = (byte)0x0B; + static final byte SMB_COM_CHECK_DIRECTORY = (byte)0x10; + static final byte SMB_COM_TRANSACTION = (byte)0x25; + static final byte SMB_COM_TRANSACTION_SECONDARY = (byte)0x26; + static final byte SMB_COM_MOVE = (byte)0x2A; + static final byte SMB_COM_ECHO = (byte)0x2B; + static final byte SMB_COM_OPEN_ANDX = (byte)0x2D; + static final byte SMB_COM_READ_ANDX = (byte)0x2E; + static final byte SMB_COM_WRITE_ANDX = (byte)0x2F; + static final byte SMB_COM_TRANSACTION2 = (byte)0x32; + static final byte SMB_COM_FIND_CLOSE2 = (byte)0x34; + static final byte SMB_COM_TREE_DISCONNECT = (byte)0x71; + static final byte SMB_COM_NEGOTIATE = (byte)0x72; + static final byte SMB_COM_SESSION_SETUP_ANDX = (byte)0x73; + static final byte SMB_COM_LOGOFF_ANDX = (byte)0x74; + static final byte SMB_COM_TREE_CONNECT_ANDX = (byte)0x75; + static final byte SMB_COM_NT_TRANSACT = (byte)0xA0; + static final byte SMB_COM_NT_TRANSACT_SECONDARY = (byte)0xA1; + static final byte SMB_COM_NT_CREATE_ANDX = (byte)0xA2; + + /* + * Some fields specify the offset from the beginning of the header. This + * field should be used for calculating that. This would likely be zero + * but an implemantation that encorporates the transport header(for + * efficiency) might use a different initial bufferIndex. For example, + * to eliminate copying data when writing NbtSession data one might + * manage that 4 byte header specifically and therefore the initial + * bufferIndex, and thus headerStart, would be 4).(NOTE: If one where + * looking for a way to improve perfomance this is precisly what you + * would want to do as the jcifs.netbios.SocketXxxputStream classes + * arraycopy all data read or written into a new buffer shifted over 4!) + */ + + byte command, flags; + int headerStart, + length, + batchLevel, + errorCode, + flags2, + tid, pid, uid, mid, + wordCount, byteCount; + boolean useUnicode, received, extendedSecurity; + long responseTimeout = 1; + int signSeq; + boolean verifyFailed; + NtlmPasswordAuthentication auth = null; + String path; + SigningDigest digest = null; + ServerMessageBlock response; + + ServerMessageBlock() { + flags = (byte)( FLAGS_PATH_NAMES_CASELESS | FLAGS_PATH_NAMES_CANONICALIZED ); + pid = PID; + batchLevel = 0; + } + + void reset() { + flags = (byte)( FLAGS_PATH_NAMES_CASELESS | FLAGS_PATH_NAMES_CANONICALIZED ); + flags2 = 0; + errorCode = 0; + received = false; + digest = null; + } + int writeString( String str, byte[] dst, int dstIndex ) { + return writeString( str, dst, dstIndex, useUnicode ); + } + int writeString( String str, byte[] dst, int dstIndex, boolean useUnicode ) { + int start = dstIndex; + + try { + if( useUnicode ) { + // Unicode requires word alignment + if((( dstIndex - headerStart ) % 2 ) != 0 ) { + dst[dstIndex++] = (byte)'\0'; + } + System.arraycopy( str.getBytes( UNI_ENCODING ), 0, + dst, dstIndex, str.length() * 2 ); + dstIndex += str.length() * 2; + dst[dstIndex++] = (byte)'\0'; + dst[dstIndex++] = (byte)'\0'; + } else { + byte[] b = str.getBytes( OEM_ENCODING ); + System.arraycopy( b, 0, dst, dstIndex, b.length ); + dstIndex += b.length; + dst[dstIndex++] = (byte)'\0'; + } + } catch( UnsupportedEncodingException uee ) { + if( log.level > 1 ) + uee.printStackTrace( log ); + } + + return dstIndex - start; + } + String readString( byte[] src, int srcIndex ) { + return readString( src, srcIndex, 256, useUnicode ); + } + String readString( byte[] src, int srcIndex, int maxLen, boolean useUnicode ) { + int len = 0; + String str = null; + try { + if( useUnicode ) { + // Unicode requires word alignment + if((( srcIndex - headerStart ) % 2 ) != 0 ) { + srcIndex++; + } + while( src[srcIndex + len] != (byte)0x00 || + src[srcIndex + len + 1] != (byte)0x00 ) { + len += 2; + if( len > maxLen ) { +if( log.level > 0 ) +Hexdump.hexdump( System.err, src, srcIndex, maxLen < 128 ? maxLen + 8 : 128 ); + throw new RuntimeException( "zero termination not found" ); + } + } + str = new String( src, srcIndex, len, UNI_ENCODING ); + } else { + while( src[srcIndex + len] != (byte)0x00 ) { + len++; + if( len > maxLen ) { +if( log.level > 0 ) +Hexdump.hexdump( System.err, src, srcIndex, maxLen < 128 ? maxLen + 8 : 128 ); + throw new RuntimeException( "zero termination not found" ); + } + } + str = new String( src, srcIndex, len, OEM_ENCODING ); + } + } catch( UnsupportedEncodingException uee ) { + if( log.level > 1 ) + uee.printStackTrace( log ); + } + return str; + } + String readString(byte[] src, int srcIndex, int srcEnd, int maxLen, boolean useUnicode) { + int len = 0; + String str = null; + try { + if (useUnicode) { + // Unicode requires word alignment + if (((srcIndex - headerStart) % 2) != 0) { + srcIndex++; + } + for (len = 0; (srcIndex + len + 1) < srcEnd; len += 2) { + if (src[srcIndex + len] == (byte)0x00 && src[srcIndex + len + 1] == (byte)0x00) { + break; + } + if (len > maxLen) { + if (log.level > 0) + Hexdump.hexdump(System.err, src, srcIndex, maxLen < 128 ? maxLen + 8 : 128); + throw new RuntimeException("zero termination not found"); + } + } + str = new String(src, srcIndex, len, UNI_ENCODING); + } else { + for (len = 0; srcIndex < srcEnd; len++) { + if (src[srcIndex + len] == (byte)0x00) { + break; + } + if (len > maxLen) { + if (log.level > 0) + Hexdump.hexdump(System.err, src, srcIndex, maxLen < 128 ? maxLen + 8 : 128); + throw new RuntimeException("zero termination not found"); + } + } + str = new String(src, srcIndex, len, OEM_ENCODING); + } + } catch( UnsupportedEncodingException uee ) { + if( log.level > 1 ) + uee.printStackTrace( log ); + } + return str; + } + int stringWireLength( String str, int offset ) { + int len = str.length() + 1; + if( useUnicode ) { + len = str.length() * 2 + 2; + len = ( offset % 2 ) != 0 ? len + 1 : len; + } + return len; + } + int readStringLength( byte[] src, int srcIndex, int max ) { + int len = 0; + while( src[srcIndex + len] != (byte)0x00 ) { + if( len++ > max ) { + throw new RuntimeException( "zero termination not found: " + this ); + } + } + return len; + } + int encode( byte[] dst, int dstIndex ) { + int start = headerStart = dstIndex; + + dstIndex += writeHeaderWireFormat( dst, dstIndex ); + wordCount = writeParameterWordsWireFormat( dst, dstIndex + 1 ); + dst[dstIndex++] = (byte)(( wordCount / 2 ) & 0xFF ); + dstIndex += wordCount; + wordCount /= 2; + byteCount = writeBytesWireFormat( dst, dstIndex + 2 ); + dst[dstIndex++] = (byte)( byteCount & 0xFF ); + dst[dstIndex++] = (byte)(( byteCount >> 8 ) & 0xFF ); + dstIndex += byteCount; + + length = dstIndex - start; + + if( digest != null ) { + digest.sign( dst, headerStart, length, this, response ); + } + + return length; + } + int decode( byte[] buffer, int bufferIndex ) { + int start = headerStart = bufferIndex; + + bufferIndex += readHeaderWireFormat( buffer, bufferIndex ); + + wordCount = buffer[bufferIndex++]; + if( wordCount != 0 ) { + int n; + if(( n = readParameterWordsWireFormat( buffer, bufferIndex )) != wordCount * 2 ) { + if( log.level >= 5 ) { + log.println( "wordCount * 2=" + ( wordCount * 2 ) + + " but readParameterWordsWireFormat returned " + n ); + } + } + bufferIndex += wordCount * 2; + } + + byteCount = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + + if( byteCount != 0 ) { + int n; + if(( n = readBytesWireFormat( buffer, bufferIndex )) != byteCount ) { + if( log.level >= 5 ) { + log.println( "byteCount=" + byteCount + + " but readBytesWireFormat returned " + n ); + } + } + // Don't think we can rely on n being correct here. Must use byteCount. + // Last paragraph of section 3.13.3 eludes to this. + + bufferIndex += byteCount; + } + + length = bufferIndex - start; + return length; + } + int writeHeaderWireFormat( byte[] dst, int dstIndex ) { + System.arraycopy( header, 0, dst, dstIndex, header.length ); + dst[dstIndex + CMD_OFFSET] = command; + dst[dstIndex + FLAGS_OFFSET] = flags; + writeInt2( flags2, dst, dstIndex + FLAGS_OFFSET + 1 ); + dstIndex += TID_OFFSET; + writeInt2( tid, dst, dstIndex ); + writeInt2( pid, dst, dstIndex + 2 ); + writeInt2( uid, dst, dstIndex + 4 ); + writeInt2( mid, dst, dstIndex + 6 ); + return HEADER_LENGTH; + } + int readHeaderWireFormat( byte[] buffer, int bufferIndex ) { + command = buffer[bufferIndex + CMD_OFFSET]; + errorCode = readInt4( buffer, bufferIndex + ERROR_CODE_OFFSET ); + flags = buffer[bufferIndex + FLAGS_OFFSET]; + flags2 = readInt2( buffer, bufferIndex + FLAGS_OFFSET + 1 ); + tid = readInt2( buffer, bufferIndex + TID_OFFSET ); + pid = readInt2( buffer, bufferIndex + TID_OFFSET + 2 ); + uid = readInt2( buffer, bufferIndex + TID_OFFSET + 4 ); + mid = readInt2( buffer, bufferIndex + TID_OFFSET + 6 ); + return HEADER_LENGTH; + } + boolean isResponse() { + return ( flags & FLAGS_RESPONSE ) == FLAGS_RESPONSE; + } + + /* + * For this packet deconstruction technique to work for + * other networking protocols the InputStream may need + * to be passed to the readXxxWireFormat methods. This is + * actually purer. However, in the case of smb we know the + * wordCount and byteCount. And since every subclass of + * ServerMessageBlock would have to perform the same read + * operation on the input stream, we might as will pull that + * common functionality into the superclass and read wordCount + * and byteCount worth of data. + * + * We will still use the readXxxWireFormat return values to + * indicate how many bytes(note: readParameterWordsWireFormat + * returns bytes read and not the number of words(but the + * wordCount member DOES store the number of words)) we + * actually read. Incedentally this is important to the + * AndXServerMessageBlock class that needs to potentially + * read in another smb's parameter words and bytes based on + * information in it's andxCommand, andxOffset, ...etc. + */ + + abstract int writeParameterWordsWireFormat( byte[] dst, int dstIndex ); + abstract int writeBytesWireFormat( byte[] dst, int dstIndex ); + abstract int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ); + abstract int readBytesWireFormat( byte[] buffer, int bufferIndex ); + + public int hashCode() { + return mid; + } + public boolean equals( Object obj ) { + return obj instanceof ServerMessageBlock && ((ServerMessageBlock)obj).mid == mid; + } + public String toString() { + String c; + switch( command ) { + case SMB_COM_NEGOTIATE: + c = "SMB_COM_NEGOTIATE"; + break; + case SMB_COM_SESSION_SETUP_ANDX: + c = "SMB_COM_SESSION_SETUP_ANDX"; + break; + case SMB_COM_TREE_CONNECT_ANDX: + c = "SMB_COM_TREE_CONNECT_ANDX"; + break; + case SMB_COM_QUERY_INFORMATION: + c = "SMB_COM_QUERY_INFORMATION"; + break; + case SMB_COM_CHECK_DIRECTORY: + c = "SMB_COM_CHECK_DIRECTORY"; + break; + case SMB_COM_TRANSACTION: + c = "SMB_COM_TRANSACTION"; + break; + case SMB_COM_TRANSACTION2: + c = "SMB_COM_TRANSACTION2"; + break; + case SMB_COM_TRANSACTION_SECONDARY: + c = "SMB_COM_TRANSACTION_SECONDARY"; + break; + case SMB_COM_FIND_CLOSE2: + c = "SMB_COM_FIND_CLOSE2"; + break; + case SMB_COM_TREE_DISCONNECT: + c = "SMB_COM_TREE_DISCONNECT"; + break; + case SMB_COM_LOGOFF_ANDX: + c = "SMB_COM_LOGOFF_ANDX"; + break; + case SMB_COM_ECHO: + c = "SMB_COM_ECHO"; + break; + case SMB_COM_MOVE: + c = "SMB_COM_MOVE"; + break; + case SMB_COM_RENAME: + c = "SMB_COM_RENAME"; + break; + case SMB_COM_DELETE: + c = "SMB_COM_DELETE"; + break; + case SMB_COM_DELETE_DIRECTORY: + c = "SMB_COM_DELETE_DIRECTORY"; + break; + case SMB_COM_NT_CREATE_ANDX: + c = "SMB_COM_NT_CREATE_ANDX"; + break; + case SMB_COM_OPEN_ANDX: + c = "SMB_COM_OPEN_ANDX"; + break; + case SMB_COM_READ_ANDX: + c = "SMB_COM_READ_ANDX"; + break; + case SMB_COM_CLOSE: + c = "SMB_COM_CLOSE"; + break; + case SMB_COM_WRITE_ANDX: + c = "SMB_COM_WRITE_ANDX"; + break; + case SMB_COM_CREATE_DIRECTORY: + c = "SMB_COM_CREATE_DIRECTORY"; + break; + case SMB_COM_NT_TRANSACT: + c = "SMB_COM_NT_TRANSACT"; + break; + case SMB_COM_NT_TRANSACT_SECONDARY: + c = "SMB_COM_NT_TRANSACT_SECONDARY"; + break; + default: + c = "UNKNOWN"; + } + String str = errorCode == 0 ? "0" : SmbException.getMessageByCode( errorCode ); + return new String( + "command=" + c + + ",received=" + received + + ",errorCode=" + str + + ",flags=0x" + Hexdump.toHexString( flags & 0xFF, 4 ) + + ",flags2=0x" + Hexdump.toHexString( flags2, 4 ) + + ",signSeq=" + signSeq + + ",tid=" + tid + + ",pid=" + pid + + ",uid=" + uid + + ",mid=" + mid + + ",wordCount=" + wordCount + + ",byteCount=" + byteCount ); + } +} diff --git a/src/jcifs/smb/SigningDigest.java b/src/jcifs/smb/SigningDigest.java new file mode 100644 index 0000000..e502e89 --- /dev/null +++ b/src/jcifs/smb/SigningDigest.java @@ -0,0 +1,196 @@ +package jcifs.smb; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.io.IOException; +import jcifs.Config; +import jcifs.util.LogStream; +import jcifs.util.Hexdump; + +/** + * To filter 0 len updates and for debugging + */ + +public class SigningDigest implements SmbConstants { + + static LogStream log = LogStream.getInstance(); + + private MessageDigest digest; + private byte[] macSigningKey; + private boolean bypass = false; + private int updates; + private int signSequence; + + public SigningDigest(byte[] macSigningKey, boolean bypass) throws SmbException { + try { + digest = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException ex) { + if( log.level > 0 ) + ex.printStackTrace( log ); + throw new SmbException( "MD5", ex ); + } + + this.macSigningKey = macSigningKey; + this.bypass = bypass; + this.updates = 0; + this.signSequence = 0; + + if( log.level >= 5 ) { + log.println("macSigningKey:"); + Hexdump.hexdump( log, macSigningKey, 0, macSigningKey.length ); + } + } + + public SigningDigest( SmbTransport transport, + NtlmPasswordAuthentication auth ) throws SmbException { + try { + digest = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException ex) { + if( log.level > 0 ) + ex.printStackTrace( log ); + throw new SmbException( "MD5", ex ); + } + + try { + switch (LM_COMPATIBILITY) { + case 0: + case 1: + case 2: + macSigningKey = new byte[40]; + auth.getUserSessionKey(transport.server.encryptionKey, macSigningKey, 0); + System.arraycopy(auth.getUnicodeHash(transport.server.encryptionKey), + 0, macSigningKey, 16, 24); + break; + case 3: + case 4: + case 5: + macSigningKey = new byte[16]; + auth.getUserSessionKey(transport.server.encryptionKey, macSigningKey, 0); + break; + default: + macSigningKey = new byte[40]; + auth.getUserSessionKey(transport.server.encryptionKey, macSigningKey, 0); + System.arraycopy(auth.getUnicodeHash(transport.server.encryptionKey), + 0, macSigningKey, 16, 24); + break; + } + } catch( Exception ex ) { + throw new SmbException( "", ex ); + } + if( log.level >= 5 ) { + log.println( "LM_COMPATIBILITY=" + LM_COMPATIBILITY ); + Hexdump.hexdump( log, macSigningKey, 0, macSigningKey.length ); + } + } + + public void update( byte[] input, int offset, int len ) { + if( log.level >= 5 ) { + log.println( "update: " + updates + " " + offset + ":" + len ); + Hexdump.hexdump( log, input, offset, Math.min( len, 256 )); + log.flush(); + } + if( len == 0 ) { + return; /* CRITICAL */ + } + digest.update( input, offset, len ); + updates++; + } + public byte[] digest() { + byte[] b; + + b = digest.digest(); + + if( log.level >= 5 ) { + log.println( "digest: " ); + Hexdump.hexdump( log, b, 0, b.length ); + log.flush(); + } + updates = 0; + + return b; + } + + /** + * Performs MAC signing of the SMB. This is done as follows. + * The signature field of the SMB is overwritted with the sequence number; + * The MD5 digest of the MAC signing key + the entire SMB is taken; + * The first 8 bytes of this are placed in the signature field. + * + * @param data The data. + * @param offset The starting offset at which the SMB header begins. + * @param length The length of the SMB data starting at offset. + */ + void sign(byte[] data, int offset, int length, + ServerMessageBlock request, ServerMessageBlock response) { + request.signSeq = signSequence; + if( response != null ) { + response.signSeq = signSequence + 1; + response.verifyFailed = false; + } + + try { + update(macSigningKey, 0, macSigningKey.length); + int index = offset + ServerMessageBlock.SIGNATURE_OFFSET; + for (int i = 0; i < 8; i++) data[index + i] = 0; + ServerMessageBlock.writeInt4(signSequence, data, index); + update(data, offset, length); + System.arraycopy(digest(), 0, data, index, 8); + if (bypass) { + bypass = false; + System.arraycopy("BSRSPYL ".getBytes(), 0, data, index, 8); + } + } catch (Exception ex) { + if( log.level > 0 ) + ex.printStackTrace( log ); + } finally { + signSequence += 2; + } + } + + /** + * Performs MAC signature verification. This calculates the signature + * of the SMB and compares it to the signature field on the SMB itself. + * + * @param data The data. + * @param offset The starting offset at which the SMB header begins. + * @param length The length of the SMB data starting at offset. + */ + boolean verify(byte[] data, int offset, ServerMessageBlock response) { + update(macSigningKey, 0, macSigningKey.length); + int index = offset; + update(data, index, ServerMessageBlock.SIGNATURE_OFFSET); + index += ServerMessageBlock.SIGNATURE_OFFSET; + byte[] sequence = new byte[8]; + ServerMessageBlock.writeInt4(response.signSeq, sequence, 0); + update(sequence, 0, sequence.length); + index += 8; + if( response.command == ServerMessageBlock.SMB_COM_READ_ANDX ) { + /* SmbComReadAndXResponse reads directly from the stream into separate byte[] b. + */ + SmbComReadAndXResponse raxr = (SmbComReadAndXResponse)response; + int length = response.length - raxr.dataLength; + update(data, index, length - ServerMessageBlock.SIGNATURE_OFFSET - 8); + update(raxr.b, raxr.off, raxr.dataLength); + } else { + update(data, index, response.length - ServerMessageBlock.SIGNATURE_OFFSET - 8); + } + byte[] signature = digest(); + for (int i = 0; i < 8; i++) { + if (signature[i] != data[offset + ServerMessageBlock.SIGNATURE_OFFSET + i]) { + if( log.level >= 2 ) { + log.println( "signature verification failure" ); + Hexdump.hexdump( log, signature, 0, 8 ); + Hexdump.hexdump( log, data, + offset + ServerMessageBlock.SIGNATURE_OFFSET, 8 ); + } + return response.verifyFailed = true; + } + } + + return response.verifyFailed = false; + } + public String toString() { + return "LM_COMPATIBILITY=" + LM_COMPATIBILITY + " MacSigningKey=" + Hexdump.toHexString(macSigningKey, 0, macSigningKey.length); + } +} + diff --git a/src/jcifs/smb/SmbAuthException.java b/src/jcifs/smb/SmbAuthException.java new file mode 100644 index 0000000..78c86ee --- /dev/null +++ b/src/jcifs/smb/SmbAuthException.java @@ -0,0 +1,33 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +/** + * The SmbAuthException encapsulates the variety of + * authentication related error codes returned by an SMB server. + *

+ * See jCIFS Exceptions and NtlmAuthenticator for more information about SmbAuthException. + */ + +public class SmbAuthException extends SmbException { + + SmbAuthException( int errcode ) { + super( errcode, null ); + } +} diff --git a/src/jcifs/smb/SmbComBlankResponse.java b/src/jcifs/smb/SmbComBlankResponse.java new file mode 100644 index 0000000..d4ceab5 --- /dev/null +++ b/src/jcifs/smb/SmbComBlankResponse.java @@ -0,0 +1,42 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComBlankResponse extends ServerMessageBlock { + + SmbComBlankResponse() { + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComBlankResponse[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComCheckDirectory.jav b/src/jcifs/smb/SmbComCheckDirectory.jav new file mode 100644 index 0000000..070a6a6 --- /dev/null +++ b/src/jcifs/smb/SmbComCheckDirectory.jav @@ -0,0 +1,52 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComCheckDirectory extends ServerMessageBlock { + + String directoryPath; + + SmbComCheckDirectory( String directoryPath ) { + command = SMB_COM_CHECK_DIRECTORY; + this.directoryPath = directoryPath; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + dst[dstIndex++] = (byte)0x04; + dstIndex += writeString( directoryPath, dst, dstIndex ); + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComCheckDirectory[" + + super.toString() + + ",directoryPath=" + directoryPath + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComClose.java b/src/jcifs/smb/SmbComClose.java new file mode 100644 index 0000000..6624e11 --- /dev/null +++ b/src/jcifs/smb/SmbComClose.java @@ -0,0 +1,55 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Date; + +class SmbComClose extends ServerMessageBlock { + + private int fid; + private long lastWriteTime; + + SmbComClose( int fid, long lastWriteTime ) { + this.fid = fid; + this.lastWriteTime = lastWriteTime; + command = SMB_COM_CLOSE; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + writeInt2( fid, dst, dstIndex ); + dstIndex += 2; + writeUTime( lastWriteTime, dst, dstIndex ); + return 6; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComClose[" + + super.toString() + + ",fid=" + fid + + ",lastWriteTime=" + lastWriteTime + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComCreateDirectory.java b/src/jcifs/smb/SmbComCreateDirectory.java new file mode 100644 index 0000000..78b2fd9 --- /dev/null +++ b/src/jcifs/smb/SmbComCreateDirectory.java @@ -0,0 +1,50 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComCreateDirectory extends ServerMessageBlock { + + SmbComCreateDirectory( String directoryName ) { + this.path = directoryName; + command = SMB_COM_CREATE_DIRECTORY; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + dst[dstIndex++] = (byte)0x04; + dstIndex += writeString( path, dst, dstIndex ); + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComCreateDirectory[" + + super.toString() + + ",directoryName=" + path + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComDelete.java b/src/jcifs/smb/SmbComDelete.java new file mode 100644 index 0000000..9313124 --- /dev/null +++ b/src/jcifs/smb/SmbComDelete.java @@ -0,0 +1,57 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.util.Hexdump; + +class SmbComDelete extends ServerMessageBlock { + + private int searchAttributes; + + SmbComDelete( String fileName ) { + this.path = fileName; + command = SMB_COM_DELETE; + searchAttributes = ATTR_HIDDEN | ATTR_HIDDEN | ATTR_SYSTEM; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + writeInt2( searchAttributes, dst, dstIndex ); + return 2; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + dst[dstIndex++] = (byte)0x04; + dstIndex += writeString( path, dst, dstIndex ); + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComDelete[" + + super.toString() + + ",searchAttributes=0x" + Hexdump.toHexString( searchAttributes, 4 ) + + ",fileName=" + path + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComDeleteDirectory.java b/src/jcifs/smb/SmbComDeleteDirectory.java new file mode 100644 index 0000000..f321ef7 --- /dev/null +++ b/src/jcifs/smb/SmbComDeleteDirectory.java @@ -0,0 +1,50 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComDeleteDirectory extends ServerMessageBlock { + + SmbComDeleteDirectory( String directoryName ) { + this.path = directoryName; + command = SMB_COM_DELETE_DIRECTORY; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + dst[dstIndex++] = (byte)0x04; + dstIndex += writeString( path, dst, dstIndex ); + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComDeleteDirectory[" + + super.toString() + + ",directoryName=" + path + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComEcho.jav b/src/jcifs/smb/SmbComEcho.jav new file mode 100644 index 0000000..5a5f2f2 --- /dev/null +++ b/src/jcifs/smb/SmbComEcho.jav @@ -0,0 +1,49 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComEcho extends ServerMessageBlock { + + int echoCount; + + SmbComEcho( int echoCount ) { + command = SMB_COM_ECHO; + this.echoCount = echoCount; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + writeInt2( echoCount, dst, dstIndex ); + return 2; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex] = (byte)'M'; + return 1; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComEcho[" + + super.toString() + + ",echoCount=" + echoCount + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComEchoResponse.jav b/src/jcifs/smb/SmbComEchoResponse.jav new file mode 100644 index 0000000..3a5d3e1 --- /dev/null +++ b/src/jcifs/smb/SmbComEchoResponse.jav @@ -0,0 +1,45 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComEchoResponse extends ServerMessageBlock { + + int sequenceNumber; + + SmbComEchoResponse() { + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + sequenceNumber = readInt2( buffer, bufferIndex ); + return 2; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 1; + } + public String toString() { + return new String( "SmbComEchoResponse[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComFindClose2.java b/src/jcifs/smb/SmbComFindClose2.java new file mode 100644 index 0000000..4272759 --- /dev/null +++ b/src/jcifs/smb/SmbComFindClose2.java @@ -0,0 +1,48 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComFindClose2 extends ServerMessageBlock { + + private int sid; + + SmbComFindClose2( int sid ) { + this.sid = sid; + command = SMB_COM_FIND_CLOSE2; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + writeInt2( sid, dst, dstIndex ); + return 2; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComFindClose2[" + + super.toString() + + ",sid=" + sid + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComLogoffAndX.java b/src/jcifs/smb/SmbComLogoffAndX.java new file mode 100644 index 0000000..798bbfc --- /dev/null +++ b/src/jcifs/smb/SmbComLogoffAndX.java @@ -0,0 +1,44 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComLogoffAndX extends AndXServerMessageBlock { + + SmbComLogoffAndX( ServerMessageBlock andx ) { + super( andx ); + command = SMB_COM_LOGOFF_ANDX; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComLogoffAndX[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComNTCreateAndX.java b/src/jcifs/smb/SmbComNTCreateAndX.java new file mode 100644 index 0000000..8c46f7e --- /dev/null +++ b/src/jcifs/smb/SmbComNTCreateAndX.java @@ -0,0 +1,195 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.util.Hexdump; + +class SmbComNTCreateAndX extends AndXServerMessageBlock { + + // share access specified in SmbFile + + // create disposition + + /* Creates a new file or supersedes the existing one + */ + + static final int FILE_SUPERSEDE = 0x0; + + /* Open the file or fail if it does not exist + * aka OPEN_EXISTING + */ + + static final int FILE_OPEN = 0x1; + + /* Create the file or fail if it does not exist + * aka CREATE_NEW + */ + + static final int FILE_CREATE = 0x2; + + /* Open the file or create it if it does not exist + * aka OPEN_ALWAYS + */ + + static final int FILE_OPEN_IF = 0x3; + + /* Open the file and overwrite it's contents or fail if it does not exist + * aka TRUNCATE_EXISTING + */ + + static final int FILE_OVERWRITE = 0x4; + + /* Open the file and overwrite it's contents or create it if it does not exist + * aka CREATE_ALWAYS (according to the wire when calling CreateFile) + */ + + static final int FILE_OVERWRITE_IF = 0x5; + + + // create options + static final int FILE_WRITE_THROUGH = 0x00000002; + static final int FILE_SEQUENTIAL_ONLY = 0x00000004; + static final int FILE_SYNCHRONOUS_IO_ALERT = 0x00000010; + static final int FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020; + + // security flags + static final int SECURITY_CONTEXT_TRACKING = 0x01; + static final int SECURITY_EFFECTIVE_ONLY = 0x02; + + private int rootDirectoryFid, + extFileAttributes, + shareAccess, + createDisposition, + createOptions, + impersonationLevel; + private long allocationSize; + private byte securityFlags; + private int namelen_index; + +int flags0, desiredAccess; + + SmbComNTCreateAndX( String name, int flags, + int access, + int shareAccess, + int extFileAttributes, + int createOptions, + ServerMessageBlock andx ) { + super( andx ); + this.path = name; + command = SMB_COM_NT_CREATE_ANDX; + + desiredAccess = access; + desiredAccess |= FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES; + + // extFileAttributes + this.extFileAttributes = extFileAttributes; + + // shareAccess + this.shareAccess = shareAccess; + + // createDisposition + if(( flags & SmbFile.O_TRUNC ) == SmbFile.O_TRUNC ) { + // truncate the file + if(( flags & SmbFile.O_CREAT ) == SmbFile.O_CREAT ) { + // create it if necessary + createDisposition = FILE_OVERWRITE_IF; + } else { + createDisposition = FILE_OVERWRITE; + } + } else { + // don't truncate the file + if(( flags & SmbFile.O_CREAT ) == SmbFile.O_CREAT ) { + // create it if necessary + if ((flags & SmbFile.O_EXCL ) == SmbFile.O_EXCL ) { + // fail if already exists + createDisposition = FILE_CREATE; + } else { + createDisposition = FILE_OPEN_IF; + } + } else { + createDisposition = FILE_OPEN; + } + } + + if ((createOptions & 0x0001) == 0) { + this.createOptions = createOptions | 0x0040; + } else { + this.createOptions = createOptions; + } + impersonationLevel = 0x02; // As seen on NT :~) + securityFlags = (byte)0x03; // SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + dst[dstIndex++] = (byte)0x00; + // name length without counting null termination + namelen_index = dstIndex; + dstIndex += 2; + writeInt4( flags0, dst, dstIndex ); + dstIndex += 4; + writeInt4( rootDirectoryFid, dst, dstIndex ); + dstIndex += 4; + writeInt4( desiredAccess, dst, dstIndex ); + dstIndex += 4; + writeInt8( allocationSize, dst, dstIndex ); + dstIndex += 8; + writeInt4( extFileAttributes, dst, dstIndex ); + dstIndex += 4; + writeInt4( shareAccess, dst, dstIndex ); + dstIndex += 4; + writeInt4( createDisposition, dst, dstIndex ); + dstIndex += 4; + writeInt4( createOptions, dst, dstIndex ); + dstIndex += 4; + writeInt4( impersonationLevel, dst, dstIndex ); + dstIndex += 4; + dst[dstIndex++] = securityFlags; + + return dstIndex - start; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int n; + n = writeString( path, dst, dstIndex ); + writeInt2( ( useUnicode ? path.length() * 2 : n ), dst, namelen_index ); + return n; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComNTCreateAndX[" + + super.toString() + + ",flags=0x" + Hexdump.toHexString( flags0, 2 ) + + ",rootDirectoryFid=" + rootDirectoryFid + + ",desiredAccess=0x" + Hexdump.toHexString( desiredAccess, 4 ) + + ",allocationSize=" + allocationSize + + ",extFileAttributes=0x" + Hexdump.toHexString( extFileAttributes, 4 ) + + ",shareAccess=0x" + Hexdump.toHexString( shareAccess, 4 ) + + ",createDisposition=0x" + Hexdump.toHexString( createDisposition, 4 ) + + ",createOptions=0x" + Hexdump.toHexString( createOptions, 8 ) + + ",impersonationLevel=0x" + Hexdump.toHexString( impersonationLevel, 4 ) + + ",securityFlags=0x" + Hexdump.toHexString( securityFlags, 2 ) + + ",name=" + path + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComNTCreateAndXResponse.java b/src/jcifs/smb/SmbComNTCreateAndXResponse.java new file mode 100644 index 0000000..e45e2e2 --- /dev/null +++ b/src/jcifs/smb/SmbComNTCreateAndXResponse.java @@ -0,0 +1,104 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Date; +import jcifs.util.Hexdump; + +class SmbComNTCreateAndXResponse extends AndXServerMessageBlock { + + static final int EXCLUSIVE_OPLOCK_GRANTED = 1; + static final int BATCH_OPLOCK_GRANTED = 2; + static final int LEVEL_II_OPLOCK_GRANTED = 3; + + byte oplockLevel; + int fid, + createAction, + extFileAttributes, + fileType, + deviceState; + long creationTime, + lastAccessTime, + lastWriteTime, + changeTime, + allocationSize, + endOfFile; + boolean directory; +boolean isExtended; + + SmbComNTCreateAndXResponse() { + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + oplockLevel = buffer[bufferIndex++]; + fid = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + createAction = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + creationTime = readTime( buffer, bufferIndex ); + bufferIndex += 8; + lastAccessTime = readTime( buffer, bufferIndex ); + bufferIndex += 8; + lastWriteTime = readTime( buffer, bufferIndex ); + bufferIndex += 8; + changeTime = readTime( buffer, bufferIndex ); + bufferIndex += 8; + extFileAttributes = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + allocationSize = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + endOfFile = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + fileType = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + deviceState = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + directory = ( buffer[bufferIndex++] & 0xFF ) > 0; + + return bufferIndex - start; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComNTCreateAndXResponse[" + + super.toString() + + ",oplockLevel=" + oplockLevel + + ",fid=" + fid + + ",createAction=0x" + Hexdump.toHexString( createAction, 4 ) + + ",creationTime=" + new Date( creationTime ) + + ",lastAccessTime=" + new Date( lastAccessTime ) + + ",lastWriteTime=" + new Date( lastWriteTime ) + + ",changeTime=" + new Date( changeTime ) + + ",extFileAttributes=0x" + Hexdump.toHexString( extFileAttributes, 4 ) + + ",allocationSize=" + allocationSize + + ",endOfFile=" + endOfFile + + ",fileType=" + fileType + + ",deviceState=" + deviceState + + ",directory=" + directory + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComNegotiate.java b/src/jcifs/smb/SmbComNegotiate.java new file mode 100644 index 0000000..c9da5cc --- /dev/null +++ b/src/jcifs/smb/SmbComNegotiate.java @@ -0,0 +1,58 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.UnsupportedEncodingException; + +class SmbComNegotiate extends ServerMessageBlock { + + private static final String DIALECTS = "\u0002NT LM 0.12\u0000"; + + SmbComNegotiate() { + command = SMB_COM_NEGOTIATE; + flags2 = DEFAULT_FLAGS2; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + byte[] dialects; + try { + dialects = DIALECTS.getBytes( "ASCII" ); + } catch( UnsupportedEncodingException uee ) { + return 0; + } + System.arraycopy( dialects, 0, dst, dstIndex, dialects.length ); + return dialects.length; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComNegotiate[" + + super.toString() + + ",wordCount=" + wordCount + + ",dialects=NT LM 0.12]" ); + } +} + diff --git a/src/jcifs/smb/SmbComNegotiateResponse.java b/src/jcifs/smb/SmbComNegotiateResponse.java new file mode 100644 index 0000000..3b60392 --- /dev/null +++ b/src/jcifs/smb/SmbComNegotiateResponse.java @@ -0,0 +1,136 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Date; +import java.io.UnsupportedEncodingException; +import jcifs.util.Hexdump; + +class SmbComNegotiateResponse extends ServerMessageBlock { + + int dialectIndex; + SmbTransport.ServerData server; + + SmbComNegotiateResponse( SmbTransport.ServerData server ) { + this.server = server; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, + int bufferIndex ) { + int start = bufferIndex; + + dialectIndex = readInt2( buffer, bufferIndex ); bufferIndex += 2; + if( dialectIndex > 10 ) { + return bufferIndex - start; + } + server.securityMode = buffer[bufferIndex++] & 0xFF; + server.security = server.securityMode & 0x01; + server.encryptedPasswords = ( server.securityMode & 0x02 ) == 0x02; + server.signaturesEnabled = ( server.securityMode & 0x04 ) == 0x04; + server.signaturesRequired = ( server.securityMode & 0x08 ) == 0x08; + server.maxMpxCount = readInt2( buffer, bufferIndex ); bufferIndex += 2; + server.maxNumberVcs = readInt2( buffer, bufferIndex ); bufferIndex += 2; + server.maxBufferSize = readInt4( buffer, bufferIndex ); bufferIndex += 4; + server.maxRawSize = readInt4( buffer, bufferIndex ); bufferIndex += 4; + server.sessionKey = readInt4( buffer, bufferIndex ); bufferIndex += 4; + server.capabilities = readInt4( buffer, bufferIndex ); bufferIndex += 4; + server.serverTime = readTime( buffer, bufferIndex ); bufferIndex += 8; + server.serverTimeZone = readInt2( buffer, bufferIndex ); bufferIndex += 2; + server.encryptionKeyLength = buffer[bufferIndex++] & 0xFF; + + return bufferIndex - start; + } + int readBytesWireFormat( byte[] buffer, + int bufferIndex ) { + int start = bufferIndex; + + if ((server.capabilities & CAP_EXTENDED_SECURITY) == 0) { + server.encryptionKey = new byte[server.encryptionKeyLength]; + System.arraycopy( buffer, bufferIndex, + server.encryptionKey, 0, server.encryptionKeyLength ); + bufferIndex += server.encryptionKeyLength; + if( byteCount > server.encryptionKeyLength ) { + int len = 0; +// TODO: we can use new string routine here + try { + if(( flags2 & FLAGS2_UNICODE ) == FLAGS2_UNICODE ) { + while( buffer[bufferIndex + len] != (byte)0x00 || + buffer[bufferIndex + len + 1] != (byte)0x00 ) { + len += 2; + if( len > 256 ) { + throw new RuntimeException( "zero termination not found" ); + } + } + server.oemDomainName = new String( buffer, bufferIndex, + len, UNI_ENCODING ); + } else { + while( buffer[bufferIndex + len] != (byte)0x00 ) { + len++; + if( len > 256 ) { + throw new RuntimeException( "zero termination not found" ); + } + } + server.oemDomainName = new String( buffer, bufferIndex, + len, ServerMessageBlock.OEM_ENCODING ); + } + } catch( UnsupportedEncodingException uee ) { + if( log.level > 1 ) + uee.printStackTrace( log ); + } + bufferIndex += len; + } else { + server.oemDomainName = new String(); + } + } else { + server.guid = new byte[16]; + System.arraycopy(buffer, bufferIndex, server.guid, 0, 16); + server.oemDomainName = new String(); + // ignore SPNEGO token for now ... + } + + return bufferIndex - start; + } + public String toString() { + return new String( "SmbComNegotiateResponse[" + + super.toString() + + ",wordCount=" + wordCount + + ",dialectIndex=" + dialectIndex + + ",securityMode=0x" + Hexdump.toHexString( server.securityMode, 1 ) + + ",security=" + ( server.security == SECURITY_SHARE ? "share" : "user" ) + + ",encryptedPasswords=" + server.encryptedPasswords + + ",maxMpxCount=" + server.maxMpxCount + + ",maxNumberVcs=" + server.maxNumberVcs + + ",maxBufferSize=" + server.maxBufferSize + + ",maxRawSize=" + server.maxRawSize + + ",sessionKey=0x" + Hexdump.toHexString( server.sessionKey, 8 ) + + ",capabilities=0x" + Hexdump.toHexString( server.capabilities, 8 ) + + ",serverTime=" + new Date( server.serverTime ) + + ",serverTimeZone=" + server.serverTimeZone + + ",encryptionKeyLength=" + server.encryptionKeyLength + + ",byteCount=" + byteCount + + ",oemDomainName=" + server.oemDomainName + "]" ); + } +} + diff --git a/src/jcifs/smb/SmbComNtTransaction.java b/src/jcifs/smb/SmbComNtTransaction.java new file mode 100644 index 0000000..c6126ae --- /dev/null +++ b/src/jcifs/smb/SmbComNtTransaction.java @@ -0,0 +1,82 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +abstract class SmbComNtTransaction extends SmbComTransaction { + + // relative to headerStart + private static final int NTT_PRIMARY_SETUP_OFFSET = 69; + private static final int NTT_SECONDARY_PARAMETER_OFFSET = 51; + + static final int NT_TRANSACT_QUERY_SECURITY_DESC = 6; + + int function; + + SmbComNtTransaction() { + super(); + primarySetupOffset = NTT_PRIMARY_SETUP_OFFSET; + secondaryParameterOffset = NTT_SECONDARY_PARAMETER_OFFSET; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + if (command != SMB_COM_NT_TRANSACT_SECONDARY) { + dst[dstIndex++] = maxSetupCount; + } else { + dst[dstIndex++] = (byte)0x00; // Reserved + } + dst[dstIndex++] = (byte)0x00; // Reserved + dst[dstIndex++] = (byte)0x00; // Reserved + writeInt4( totalParameterCount, dst, dstIndex ); + dstIndex += 4; + writeInt4( totalDataCount, dst, dstIndex ); + dstIndex += 4; + if (command != SMB_COM_NT_TRANSACT_SECONDARY) { + writeInt4( maxParameterCount, dst, dstIndex ); + dstIndex += 4; + writeInt4( maxDataCount, dst, dstIndex ); + dstIndex += 4; + } + writeInt4( parameterCount, dst, dstIndex ); + dstIndex += 4; + writeInt4(( parameterCount == 0 ? 0 : parameterOffset ), dst, dstIndex ); + dstIndex += 4; + if (command == SMB_COM_NT_TRANSACT_SECONDARY) { + writeInt4( parameterDisplacement, dst, dstIndex ); + dstIndex += 4; + } + writeInt4( dataCount, dst, dstIndex ); + dstIndex += 4; + writeInt4(( dataCount == 0 ? 0 : dataOffset ), dst, dstIndex ); + dstIndex += 4; + if (command == SMB_COM_NT_TRANSACT_SECONDARY) { + writeInt4( dataDisplacement, dst, dstIndex ); + dstIndex += 4; + dst[dstIndex++] = (byte)0x00; // Reserved1 + } else { + dst[dstIndex++] = (byte)setupCount; + writeInt2( function, dst, dstIndex ); + dstIndex += 2; + dstIndex += writeSetupWireFormat( dst, dstIndex ); + } + + return dstIndex - start; + } +} diff --git a/src/jcifs/smb/SmbComNtTransactionResponse.java b/src/jcifs/smb/SmbComNtTransactionResponse.java new file mode 100644 index 0000000..78a58e2 --- /dev/null +++ b/src/jcifs/smb/SmbComNtTransactionResponse.java @@ -0,0 +1,62 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +abstract class SmbComNtTransactionResponse extends SmbComTransactionResponse { + + SmbComNtTransactionResponse() { + super(); + } + + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + buffer[bufferIndex++] = (byte)0x00; // Reserved + buffer[bufferIndex++] = (byte)0x00; // Reserved + buffer[bufferIndex++] = (byte)0x00; // Reserved + + totalParameterCount = readInt4( buffer, bufferIndex ); + if( bufDataStart == 0 ) { + bufDataStart = totalParameterCount; + } + bufferIndex += 4; + totalDataCount = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + parameterCount = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + parameterOffset = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + parameterDisplacement = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + dataCount = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + dataOffset = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + dataDisplacement = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + setupCount = buffer[bufferIndex] & 0xFF; + bufferIndex += 2; + if( setupCount != 0 ) { + if( log.level >= 3 ) + log.println( "setupCount is not zero: " + setupCount ); + } + + return bufferIndex - start; + } +} diff --git a/src/jcifs/smb/SmbComOpenAndX.java b/src/jcifs/smb/SmbComOpenAndX.java new file mode 100644 index 0000000..5430d83 --- /dev/null +++ b/src/jcifs/smb/SmbComOpenAndX.java @@ -0,0 +1,157 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Date; +import jcifs.Config; +import jcifs.util.Hexdump; + +class SmbComOpenAndX extends AndXServerMessageBlock { + + // flags (not the same as flags constructor argument) + private static final int FLAGS_RETURN_ADDITIONAL_INFO = 0x01; + private static final int FLAGS_REQUEST_OPLOCK = 0x02; + private static final int FLAGS_REQUEST_BATCH_OPLOCK = 0x04; + + // Access Mode Encoding for desiredAccess + private static final int SHARING_COMPATIBILITY = 0x00; + private static final int SHARING_DENY_READ_WRITE_EXECUTE = 0x10; + private static final int SHARING_DENY_WRITE = 0x20; + private static final int SHARING_DENY_READ_EXECUTE = 0x30; + private static final int SHARING_DENY_NONE = 0x40; + + private static final int DO_NOT_CACHE = 0x1000; // bit 12 + private static final int WRITE_THROUGH = 0x4000; // bit 14 + + private static final int OPEN_FN_CREATE = 0x10; + private static final int OPEN_FN_FAIL_IF_EXISTS = 0x00; + private static final int OPEN_FN_OPEN = 0x01; + private static final int OPEN_FN_TRUNC = 0x02; + + private static final int BATCH_LIMIT = Config.getInt( "jcifs.smb.client.OpenAndX.ReadAndX", 1 ); + + int flags, + desiredAccess, + searchAttributes, + fileAttributes, + creationTime, + openFunction, + allocationSize; + + // flags is NOT the same as flags member + + SmbComOpenAndX( String fileName, int access, int flags, ServerMessageBlock andx ) { + super( andx ); + this.path = fileName; + command = SMB_COM_OPEN_ANDX; + + desiredAccess = access & 0x3; + if( desiredAccess == 0x3 ) { + desiredAccess = 0x2; /* Mmm, I thought 0x03 was RDWR */ + } + desiredAccess |= SHARING_DENY_NONE; + desiredAccess &= ~0x1; // Win98 doesn't like GENERIC_READ ?! -- get Access Denied. + + // searchAttributes + searchAttributes = ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM; + + // fileAttributes + fileAttributes = 0; + + // openFunction + if(( flags & SmbFile.O_TRUNC ) == SmbFile.O_TRUNC ) { + // truncate the file + if(( flags & SmbFile.O_CREAT ) == SmbFile.O_CREAT ) { + // create it if necessary + openFunction = OPEN_FN_TRUNC | OPEN_FN_CREATE; + } else { + openFunction = OPEN_FN_TRUNC; + } + } else { + // don't truncate the file + if(( flags & SmbFile.O_CREAT ) == SmbFile.O_CREAT ) { + // create it if necessary + if(( flags & SmbFile.O_EXCL ) == SmbFile.O_EXCL ) { + // fail if already exists + openFunction = OPEN_FN_CREATE | OPEN_FN_FAIL_IF_EXISTS; + } else { + openFunction = OPEN_FN_CREATE | OPEN_FN_OPEN; + } + } else { + openFunction = OPEN_FN_OPEN; + } + } + } + + int getBatchLimit( byte command ) { + return command == SMB_COM_READ_ANDX ? BATCH_LIMIT : 0; + } + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( flags, dst, dstIndex ); + dstIndex += 2; + writeInt2( desiredAccess, dst, dstIndex ); + dstIndex += 2; + writeInt2( searchAttributes, dst, dstIndex ); + dstIndex += 2; + writeInt2( fileAttributes, dst, dstIndex ); + dstIndex += 2; + creationTime = 0; + writeInt4( creationTime, dst, dstIndex ); + dstIndex += 4; + writeInt2( openFunction, dst, dstIndex ); + dstIndex += 2; + writeInt4( allocationSize, dst, dstIndex ); + dstIndex += 4; + for( int i = 0; i < 8; i++ ) { + dst[dstIndex++] = 0x00; + } + + return dstIndex - start; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + if( useUnicode ) { + dst[dstIndex++] = (byte)'\0'; + } + dstIndex += writeString( path, dst, dstIndex ); + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComOpenAndX[" + + super.toString() + + ",flags=0x" + Hexdump.toHexString( flags, 2 ) + + ",desiredAccess=0x" + Hexdump.toHexString( desiredAccess, 4 ) + + ",searchAttributes=0x" + Hexdump.toHexString( searchAttributes, 4 ) + + ",fileAttributes=0x" + Hexdump.toHexString( fileAttributes, 4 ) + + ",creationTime=" + new Date( creationTime ) + + ",openFunction=0x" + Hexdump.toHexString( openFunction, 2 ) + + ",allocationSize=" + allocationSize + + ",fileName=" + path + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComOpenAndXResponse.java b/src/jcifs/smb/SmbComOpenAndXResponse.java new file mode 100644 index 0000000..ded4d26 --- /dev/null +++ b/src/jcifs/smb/SmbComOpenAndXResponse.java @@ -0,0 +1,85 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.IOException; +import java.io.InputStream; + +class SmbComOpenAndXResponse extends AndXServerMessageBlock { + + int fid, + fileAttributes, + dataSize, + grantedAccess, + fileType, + deviceState, + action, + serverFid; + long lastWriteTime; + + SmbComOpenAndXResponse() { + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + fid = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + fileAttributes = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + lastWriteTime = readUTime( buffer, bufferIndex ); + bufferIndex += 4; + dataSize = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + grantedAccess = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + fileType = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + deviceState = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + action = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + serverFid = readInt4( buffer, bufferIndex ); + bufferIndex += 6; + + return bufferIndex - start; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComOpenAndXResponse[" + + super.toString() + + ",fid=" + fid + + ",fileAttributes=" + fileAttributes + + ",lastWriteTime=" + lastWriteTime + + ",dataSize=" + dataSize + + ",grantedAccess=" + grantedAccess + + ",fileType=" + fileType + + ",deviceState=" + deviceState + + ",action=" + action + + ",serverFid=" + serverFid + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComQueryInformation.java b/src/jcifs/smb/SmbComQueryInformation.java new file mode 100644 index 0000000..0f2896a --- /dev/null +++ b/src/jcifs/smb/SmbComQueryInformation.java @@ -0,0 +1,49 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComQueryInformation extends ServerMessageBlock { + + SmbComQueryInformation( String filename ) { + path = filename; + command = SMB_COM_QUERY_INFORMATION; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + dst[dstIndex++] = (byte)0x04; + dstIndex += writeString( path, dst, dstIndex ); + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComQueryInformation[" + + super.toString() + + ",filename=" + path + "]" ); + } +} + diff --git a/src/jcifs/smb/SmbComQueryInformationResponse.java b/src/jcifs/smb/SmbComQueryInformationResponse.java new file mode 100644 index 0000000..92169c9 --- /dev/null +++ b/src/jcifs/smb/SmbComQueryInformationResponse.java @@ -0,0 +1,76 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Date; +import jcifs.util.Hexdump; + +class SmbComQueryInformationResponse extends ServerMessageBlock implements Info { + + private int fileAttributes = 0x0000; + private long lastWriteTime = 0L; + private long serverTimeZoneOffset; + private int fileSize = 0; + + SmbComQueryInformationResponse( long serverTimeZoneOffset ) { + this.serverTimeZoneOffset = serverTimeZoneOffset; + command = SMB_COM_QUERY_INFORMATION; + } + + public int getAttributes() { + return fileAttributes; + } + public long getCreateTime() { + return lastWriteTime + serverTimeZoneOffset; + } + public long getLastWriteTime() { + return lastWriteTime + serverTimeZoneOffset; + } + public long getSize() { + return fileSize; + } + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + if( wordCount == 0 ) { + return 0; + } + fileAttributes = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + lastWriteTime = readUTime( buffer, bufferIndex ); + bufferIndex += 4; + fileSize = readInt4( buffer, bufferIndex ); + return 20; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComQueryInformationResponse[" + + super.toString() + + ",fileAttributes=0x" + Hexdump.toHexString( fileAttributes, 4 ) + + ",lastWriteTime=" + new Date( lastWriteTime ) + + ",fileSize=" + fileSize + "]" ); + } +} + diff --git a/src/jcifs/smb/SmbComReadAndX.java b/src/jcifs/smb/SmbComReadAndX.java new file mode 100644 index 0000000..35d7db2 --- /dev/null +++ b/src/jcifs/smb/SmbComReadAndX.java @@ -0,0 +1,95 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.Config; + +class SmbComReadAndX extends AndXServerMessageBlock { + + private static final int BATCH_LIMIT = Config.getInt( "jcifs.smb.client.ReadAndX.Close", 1 ); + + private long offset; + private int fid, + openTimeout; +int maxCount, minCount, remaining; + + SmbComReadAndX() { + super( null ); + command = SMB_COM_READ_ANDX; + openTimeout = 0xFFFFFFFF; + } + SmbComReadAndX( int fid, long offset, int maxCount, ServerMessageBlock andx ) { + super( andx ); + this.fid = fid; + this.offset = offset; + this.maxCount = minCount = maxCount; + command = SMB_COM_READ_ANDX; + openTimeout = 0xFFFFFFFF; + } + + void setParam( int fid, long offset, int maxCount ) { + this.fid = fid; + this.offset = offset; + this.maxCount = minCount = maxCount; + } + int getBatchLimit( byte command ) { + return command == SMB_COM_CLOSE ? BATCH_LIMIT : 0; + } + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( fid, dst, dstIndex ); + dstIndex += 2; + writeInt4( offset, dst, dstIndex ); + dstIndex += 4; + writeInt2( maxCount, dst, dstIndex ); + dstIndex += 2; + writeInt2( minCount, dst, dstIndex ); + dstIndex += 2; + writeInt4( openTimeout, dst, dstIndex ); + dstIndex += 4; + writeInt2( remaining, dst, dstIndex ); + dstIndex += 2; + writeInt4( offset >> 32, dst, dstIndex ); + dstIndex += 4; + + return dstIndex - start; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComReadAndX[" + + super.toString() + + ",fid=" + fid + + ",offset=" + offset + + ",maxCount=" + maxCount + + ",minCount=" + minCount + + ",openTimeout=" + openTimeout + + ",remaining=" + remaining + + ",offset=" + offset + + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComReadAndXResponse.java b/src/jcifs/smb/SmbComReadAndXResponse.java new file mode 100644 index 0000000..1c60930 --- /dev/null +++ b/src/jcifs/smb/SmbComReadAndXResponse.java @@ -0,0 +1,67 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComReadAndXResponse extends AndXServerMessageBlock { + + byte[] b; + int off, dataCompactionMode, dataLength, dataOffset; + + SmbComReadAndXResponse() { + } + SmbComReadAndXResponse( byte[] b, int off ) { + this.b = b; + this.off = off; + } + + void setParam( byte[] b, int off ) { + this.b = b; + this.off = off; + } + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + bufferIndex += 2; // reserved + dataCompactionMode = readInt2( buffer, bufferIndex ); + bufferIndex += 4; // 2 reserved + dataLength = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + dataOffset = readInt2( buffer, bufferIndex ); + bufferIndex += 12; // 10 reserved + + return bufferIndex - start; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + // handled special in SmbTransport.doRecv() + return 0; + } + public String toString() { + return new String( "SmbComReadAndXResponse[" + + super.toString() + + ",dataCompactionMode=" + dataCompactionMode + + ",dataLength=" + dataLength + + ",dataOffset=" + dataOffset + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComRename.java b/src/jcifs/smb/SmbComRename.java new file mode 100644 index 0000000..de36ad3 --- /dev/null +++ b/src/jcifs/smb/SmbComRename.java @@ -0,0 +1,66 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.util.Hexdump; + +class SmbComRename extends ServerMessageBlock { + + private int searchAttributes; + private String oldFileName; + private String newFileName; + + SmbComRename( String oldFileName, String newFileName ) { + command = SMB_COM_RENAME; + this.oldFileName = oldFileName; + this.newFileName = newFileName; + searchAttributes = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + writeInt2( searchAttributes, dst, dstIndex ); + return 2; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + dst[dstIndex++] = (byte)0x04; + dstIndex += writeString( oldFileName, dst, dstIndex ); + dst[dstIndex++] = (byte)0x04; + if( useUnicode ) { + dst[dstIndex++] = (byte)'\0'; + } + dstIndex += writeString( newFileName, dst, dstIndex ); + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComRename[" + + super.toString() + + ",searchAttributes=0x" + Hexdump.toHexString( searchAttributes, 4 ) + + ",oldFileName=" + oldFileName + + ",newFileName=" + newFileName + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComSessionSetupAndX.java b/src/jcifs/smb/SmbComSessionSetupAndX.java new file mode 100644 index 0000000..a5c986d --- /dev/null +++ b/src/jcifs/smb/SmbComSessionSetupAndX.java @@ -0,0 +1,177 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Arrays; +import jcifs.Config; + +class SmbComSessionSetupAndX extends AndXServerMessageBlock { + + private static final int BATCH_LIMIT = + Config.getInt( "jcifs.smb.client.SessionSetupAndX.TreeConnectAndX", 1 ); + private static final boolean DISABLE_PLAIN_TEXT_PASSWORDS = + Config.getBoolean( "jcifs.smb.client.disablePlainTextPasswords", true ); + + private byte[] lmHash, ntHash, blob = null; + private int sessionKey, capabilities; + private String accountName, primaryDomain; + + SmbSession session; + Object cred; + + SmbComSessionSetupAndX( SmbSession session, ServerMessageBlock andx, Object cred ) throws SmbException { + super( andx ); + command = SMB_COM_SESSION_SETUP_ANDX; + this.session = session; + this.cred = cred; + + sessionKey = session.transport.sessionKey; + capabilities = session.transport.capabilities; + + if (session.transport.server.security == SECURITY_USER) { + if (cred instanceof NtlmPasswordAuthentication) { + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)cred; + + if (auth == NtlmPasswordAuthentication.ANONYMOUS) { + lmHash = new byte[0]; + ntHash = new byte[0]; + capabilities &= ~SmbConstants.CAP_EXTENDED_SECURITY; + } else if (session.transport.server.encryptedPasswords) { + lmHash = auth.getAnsiHash( session.transport.server.encryptionKey ); + ntHash = auth.getUnicodeHash( session.transport.server.encryptionKey ); + // prohibit HTTP auth attempts for the null session + if (lmHash.length == 0 && ntHash.length == 0) { + throw new RuntimeException("Null setup prohibited."); + } + } else if( DISABLE_PLAIN_TEXT_PASSWORDS ) { + throw new RuntimeException( "Plain text passwords are disabled" ); + } else if( useUnicode ) { + // plain text + String password = auth.getPassword(); + lmHash = new byte[0]; + ntHash = new byte[(password.length() + 1) * 2]; + writeString( password, ntHash, 0 ); + } else { + // plain text + String password = auth.getPassword(); + lmHash = new byte[(password.length() + 1) * 2]; + ntHash = new byte[0]; + writeString( password, lmHash, 0 ); + } + accountName = auth.username; + if (useUnicode) + accountName = accountName.toUpperCase(); + primaryDomain = auth.domain.toUpperCase(); + } else if (cred instanceof byte[]) { + blob = (byte[])cred; + } else { + throw new SmbException("Unsupported credential type"); + } + } else if (session.transport.server.security == SECURITY_SHARE) { + if (cred instanceof NtlmPasswordAuthentication) { + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)cred; + lmHash = new byte[0]; + ntHash = new byte[0]; + accountName = auth.username; + if (useUnicode) + accountName = accountName.toUpperCase(); + primaryDomain = auth.domain.toUpperCase(); + } else { + throw new SmbException("Unsupported credential type"); + } + } else { + throw new SmbException("Unsupported"); + } + } + + int getBatchLimit( byte command ) { + return command == SMB_COM_TREE_CONNECT_ANDX ? BATCH_LIMIT : 0; + } + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( session.transport.snd_buf_size, dst, dstIndex ); + dstIndex += 2; + writeInt2( session.transport.maxMpxCount, dst, dstIndex ); + dstIndex += 2; + writeInt2( session.transport.VC_NUMBER, dst, dstIndex ); + dstIndex += 2; + writeInt4( sessionKey, dst, dstIndex ); + dstIndex += 4; + if (blob != null) { + writeInt2( blob.length, dst, dstIndex ); + dstIndex += 2; + } else { + writeInt2( lmHash.length, dst, dstIndex ); + dstIndex += 2; + writeInt2( ntHash.length, dst, dstIndex ); + dstIndex += 2; + } + dst[dstIndex++] = (byte)0x00; + dst[dstIndex++] = (byte)0x00; + dst[dstIndex++] = (byte)0x00; + dst[dstIndex++] = (byte)0x00; + writeInt4( capabilities, dst, dstIndex ); + dstIndex += 4; + + return dstIndex - start; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + if (blob != null) { + System.arraycopy(blob, 0, dst, dstIndex, blob.length ); + dstIndex += blob.length; + } else { + System.arraycopy( lmHash, 0, dst, dstIndex, lmHash.length ); + dstIndex += lmHash.length; + System.arraycopy( ntHash, 0, dst, dstIndex, ntHash.length ); + dstIndex += ntHash.length; + + dstIndex += writeString( accountName, dst, dstIndex ); + dstIndex += writeString( primaryDomain, dst, dstIndex ); + } + dstIndex += writeString( session.transport.NATIVE_OS, dst, dstIndex ); + dstIndex += writeString( session.transport.NATIVE_LANMAN, dst, dstIndex ); + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + String result = new String( "SmbComSessionSetupAndX[" + + super.toString() + + ",snd_buf_size=" + session.transport.snd_buf_size + + ",maxMpxCount=" + session.transport.maxMpxCount + + ",VC_NUMBER=" + session.transport.VC_NUMBER + + ",sessionKey=" + sessionKey + + ",lmHash.length=" + (lmHash == null ? 0 : lmHash.length) + + ",ntHash.length=" + (ntHash == null ? 0 : ntHash.length) + + ",capabilities=" + capabilities + + ",accountName=" + accountName + + ",primaryDomain=" + primaryDomain + + ",NATIVE_OS=" + session.transport.NATIVE_OS + + ",NATIVE_LANMAN=" + session.transport.NATIVE_LANMAN + "]" ); + return result; + } +} diff --git a/src/jcifs/smb/SmbComSessionSetupAndXResponse.java b/src/jcifs/smb/SmbComSessionSetupAndXResponse.java new file mode 100644 index 0000000..dfad9c6 --- /dev/null +++ b/src/jcifs/smb/SmbComSessionSetupAndXResponse.java @@ -0,0 +1,81 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.UnsupportedEncodingException; + +class SmbComSessionSetupAndXResponse extends AndXServerMessageBlock { + + private String nativeOs = ""; + private String nativeLanMan = ""; + private String primaryDomain = ""; + + boolean isLoggedInAsGuest; + byte[] blob = null; + + SmbComSessionSetupAndXResponse( ServerMessageBlock andx ) { + super( andx ); + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + isLoggedInAsGuest = ( buffer[bufferIndex] & 0x01 ) == 0x01 ? true : false; + bufferIndex += 2; + if (extendedSecurity) { + int blobLength = readInt2(buffer, bufferIndex); + bufferIndex += 2; + blob = new byte[blobLength]; + } + return bufferIndex - start; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + if (extendedSecurity) { + System.arraycopy(buffer, bufferIndex, blob, 0, blob.length); + bufferIndex += blob.length; + } + nativeOs = readString( buffer, bufferIndex ); + bufferIndex += stringWireLength( nativeOs, bufferIndex ); + nativeLanMan = readString( buffer, bufferIndex, start + byteCount, 255, useUnicode ); + bufferIndex += stringWireLength( nativeLanMan, bufferIndex ); + if (!extendedSecurity) { + primaryDomain = readString(buffer, bufferIndex, start + byteCount, 255, useUnicode); + bufferIndex += stringWireLength(primaryDomain, bufferIndex); + } + + return bufferIndex - start; + } + public String toString() { + String result = new String( "SmbComSessionSetupAndXResponse[" + + super.toString() + + ",isLoggedInAsGuest=" + isLoggedInAsGuest + + ",nativeOs=" + nativeOs + + ",nativeLanMan=" + nativeLanMan + + ",primaryDomain=" + primaryDomain + "]" ); + return result; + } +} + diff --git a/src/jcifs/smb/SmbComTransaction.java b/src/jcifs/smb/SmbComTransaction.java new file mode 100644 index 0000000..4bfd9ce --- /dev/null +++ b/src/jcifs/smb/SmbComTransaction.java @@ -0,0 +1,281 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Enumeration; +import jcifs.Config; +import jcifs.util.Hexdump; + +abstract class SmbComTransaction extends ServerMessageBlock implements Enumeration { + + private static final int DEFAULT_MAX_DATA_COUNT = + Config.getInt( "jcifs.smb.client.transaction_buf_size", + SmbComTransaction.TRANSACTION_BUF_SIZE ) - 512; + + // relative to headerStart + private static final int PRIMARY_SETUP_OFFSET = 61; + private static final int SECONDARY_PARAMETER_OFFSET = 51; + + private static final int DISCONNECT_TID = 0x01; + private static final int ONE_WAY_TRANSACTION = 0x02; + + private static final int PADDING_SIZE = 2; + + private int flags = 0x00; + private int fid; + private int pad = 0; + private int pad1 = 0; + private boolean hasMore = true; + private boolean isPrimary = true; + private int bufParameterOffset; + private int bufDataOffset; + + static final int TRANSACTION_BUF_SIZE = 0xFFFF; + + static final byte TRANS2_FIND_FIRST2 = (byte)0x01; + static final byte TRANS2_FIND_NEXT2 = (byte)0x02; + static final byte TRANS2_QUERY_FS_INFORMATION = (byte)0x03; + static final byte TRANS2_QUERY_PATH_INFORMATION = (byte)0x05; + static final byte TRANS2_GET_DFS_REFERRAL = (byte)0x10; + static final byte TRANS2_SET_FILE_INFORMATION = (byte)0x08; + + static final int NET_SHARE_ENUM = 0x0000; + static final int NET_SERVER_ENUM2 = 0x0068; + static final int NET_SERVER_ENUM3 = 0x00D7; + + static final byte TRANS_PEEK_NAMED_PIPE = (byte)0x23; + static final byte TRANS_WAIT_NAMED_PIPE = (byte)0x53; + static final byte TRANS_CALL_NAMED_PIPE = (byte)0x54; + static final byte TRANS_TRANSACT_NAMED_PIPE = (byte)0x26; + + protected int primarySetupOffset; + protected int secondaryParameterOffset; + protected int parameterCount; + protected int parameterOffset; + protected int parameterDisplacement; + protected int dataCount; + protected int dataOffset; + protected int dataDisplacement; + + int totalParameterCount; + int totalDataCount; + int maxParameterCount; + int maxDataCount = DEFAULT_MAX_DATA_COUNT; + byte maxSetupCount; + int timeout = 0; + int setupCount = 1; + byte subCommand; + String name = ""; + int maxBufferSize; // set in SmbTransport.sendTransaction() before nextElement called + + byte[] txn_buf; + + SmbComTransaction() { + maxParameterCount = 1024; + primarySetupOffset = PRIMARY_SETUP_OFFSET; + secondaryParameterOffset = SECONDARY_PARAMETER_OFFSET; + } + + void reset() { + super.reset(); + isPrimary = hasMore = true; + } + void reset( int key, String lastName ) { + reset(); + } + public boolean hasMoreElements() { + return hasMore; + } + public Object nextElement() { + if( isPrimary ) { + isPrimary = false; + + parameterOffset = primarySetupOffset + ( setupCount * 2 ) + 2; + if (command != SMB_COM_NT_TRANSACT) { + if( command == SMB_COM_TRANSACTION && isResponse() == false ) { + parameterOffset += stringWireLength( name, parameterOffset ); + } + } else if (command == SMB_COM_NT_TRANSACT) { + parameterOffset += 2; + } + pad = parameterOffset % PADDING_SIZE; + pad = pad == 0 ? 0 : PADDING_SIZE - pad; + parameterOffset += pad; + + totalParameterCount = writeParametersWireFormat( txn_buf, bufParameterOffset ); + bufDataOffset = totalParameterCount; // data comes right after data + + int available = maxBufferSize - parameterOffset; + parameterCount = Math.min( totalParameterCount, available ); + available -= parameterCount; + + dataOffset = parameterOffset + parameterCount; + pad1 = dataOffset % PADDING_SIZE; + pad1 = pad1 == 0 ? 0 : PADDING_SIZE - pad1; + dataOffset += pad1; + + totalDataCount = writeDataWireFormat( txn_buf, bufDataOffset ); + + dataCount = Math.min( totalDataCount, available ); + } else { + if (command != SMB_COM_NT_TRANSACT) { + command = SMB_COM_TRANSACTION_SECONDARY; + } else { + command = SMB_COM_NT_TRANSACT_SECONDARY; + } + // totalParameterCount and totalDataCount are set ok from primary + + parameterOffset = SECONDARY_PARAMETER_OFFSET; + if(( totalParameterCount - parameterDisplacement ) > 0 ) { + pad = parameterOffset % PADDING_SIZE; + pad = pad == 0 ? 0 : PADDING_SIZE - pad; + parameterOffset += pad; + } + + // caclulate parameterDisplacement before calculating new parameterCount + parameterDisplacement += parameterCount; + + int available = maxBufferSize - parameterOffset - pad; + parameterCount = Math.min( totalParameterCount - parameterDisplacement, available); + available -= parameterCount; + + dataOffset = parameterOffset + parameterCount; + pad1 = dataOffset % PADDING_SIZE; + pad1 = pad1 == 0 ? 0 : PADDING_SIZE - pad1; + dataOffset += pad1; + + dataDisplacement += dataCount; + + available -= pad1; + dataCount = Math.min( totalDataCount - dataDisplacement, available ); + } + if(( parameterDisplacement + parameterCount ) >= totalParameterCount && + ( dataDisplacement + dataCount ) >= totalDataCount ) { + hasMore = false; + } + return this; + } + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( totalParameterCount, dst, dstIndex ); + dstIndex += 2; + writeInt2( totalDataCount, dst, dstIndex ); + dstIndex += 2; + if( command != SMB_COM_TRANSACTION_SECONDARY ) { + writeInt2( maxParameterCount, dst, dstIndex ); + dstIndex += 2; + writeInt2( maxDataCount, dst, dstIndex ); + dstIndex += 2; + dst[dstIndex++] = maxSetupCount; + dst[dstIndex++] = (byte)0x00; // Reserved1 + writeInt2( flags, dst, dstIndex ); + dstIndex += 2; + writeInt4( timeout, dst, dstIndex ); + dstIndex += 4; + dst[dstIndex++] = (byte)0x00; // Reserved2 + dst[dstIndex++] = (byte)0x00; + } + writeInt2( parameterCount, dst, dstIndex ); + dstIndex += 2; +// writeInt2(( parameterCount == 0 ? 0 : parameterOffset ), dst, dstIndex ); + writeInt2(parameterOffset, dst, dstIndex ); + dstIndex += 2; + if( command == SMB_COM_TRANSACTION_SECONDARY ) { + writeInt2( parameterDisplacement, dst, dstIndex ); + dstIndex += 2; + } + writeInt2( dataCount, dst, dstIndex ); + dstIndex += 2; + writeInt2(( dataCount == 0 ? 0 : dataOffset ), dst, dstIndex ); + dstIndex += 2; + if( command == SMB_COM_TRANSACTION_SECONDARY ) { + writeInt2( dataDisplacement, dst, dstIndex ); + dstIndex += 2; + } else { + dst[dstIndex++] = (byte)setupCount; + dst[dstIndex++] = (byte)0x00; // Reserved3 + dstIndex += writeSetupWireFormat( dst, dstIndex ); + } + + return dstIndex - start; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + int p = pad; + + if( command == SMB_COM_TRANSACTION && isResponse() == false ) { + dstIndex += writeString( name, dst, dstIndex ); + } + + if( parameterCount > 0 ) { + while( p-- > 0 ) { + dst[dstIndex++] = (byte)0x00; // Pad + } + + System.arraycopy( txn_buf, bufParameterOffset, dst, dstIndex, parameterCount ); + dstIndex += parameterCount; + } + + if( dataCount > 0 ) { + p = pad1; + while( p-- > 0 ) { + dst[dstIndex++] = (byte)0x00; // Pad1 + } + System.arraycopy( txn_buf, bufDataOffset, dst, dstIndex, dataCount ); + bufDataOffset += dataCount; + dstIndex += dataCount; + } + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + + abstract int writeSetupWireFormat( byte[] dst, int dstIndex ); + abstract int writeParametersWireFormat( byte[] dst, int dstIndex ); + abstract int writeDataWireFormat( byte[] dst, int dstIndex ); + abstract int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ); + abstract int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ); + abstract int readDataWireFormat( byte[] buffer, int bufferIndex, int len ); + + public String toString() { + return new String( super.toString() + + ",totalParameterCount=" + totalParameterCount + + ",totalDataCount=" + totalDataCount + + ",maxParameterCount=" + maxParameterCount + + ",maxDataCount=" + maxDataCount + + ",maxSetupCount=" + (int)maxSetupCount + + ",flags=0x" + Hexdump.toHexString( flags, 2 ) + + ",timeout=" + timeout + + ",parameterCount=" + parameterCount + + ",parameterOffset=" + parameterOffset + + ",parameterDisplacement=" + parameterDisplacement + + ",dataCount=" + dataCount + + ",dataOffset=" + dataOffset + + ",dataDisplacement=" + dataDisplacement + + ",setupCount=" + setupCount + + ",pad=" + pad + + ",pad1=" + pad1 ); + } +} diff --git a/src/jcifs/smb/SmbComTransactionResponse.java b/src/jcifs/smb/SmbComTransactionResponse.java new file mode 100644 index 0000000..60c4445 --- /dev/null +++ b/src/jcifs/smb/SmbComTransactionResponse.java @@ -0,0 +1,173 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Enumeration; + +abstract class SmbComTransactionResponse extends ServerMessageBlock implements Enumeration { + + // relative to headerStart + private static final int SETUP_OFFSET = 61; + + private static final int DISCONNECT_TID = 0x01; + private static final int ONE_WAY_TRANSACTION = 0x02; + + private int pad; + private int pad1; + private boolean parametersDone, dataDone; + + protected int totalParameterCount; + protected int totalDataCount; + protected int parameterCount; + protected int parameterOffset; + protected int parameterDisplacement; + protected int dataOffset; + protected int dataDisplacement; + protected int setupCount; + protected int bufParameterStart; + protected int bufDataStart; + + int dataCount; + byte subCommand; + boolean hasMore = true; + boolean isPrimary = true; + byte[] txn_buf; + + /* for doNetEnum and doFindFirstNext */ + int status; + int numEntries; + FileEntry[] results; + + SmbComTransactionResponse() { + txn_buf = null; + } + + void reset() { + super.reset(); + bufDataStart = 0; + isPrimary = hasMore = true; + parametersDone = dataDone = false; + } + public boolean hasMoreElements() { + return errorCode == 0 && hasMore; + } + public Object nextElement() { + if( isPrimary ) { + isPrimary = false; + } + return this; + } + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + totalParameterCount = readInt2( buffer, bufferIndex ); + if( bufDataStart == 0 ) { + bufDataStart = totalParameterCount; + } + bufferIndex += 2; + totalDataCount = readInt2( buffer, bufferIndex ); + bufferIndex += 4; // Reserved + parameterCount = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + parameterOffset = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + parameterDisplacement = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + dataCount = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + dataOffset = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + dataDisplacement = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + setupCount = buffer[bufferIndex] & 0xFF; + bufferIndex += 2; + if( setupCount != 0 ) { + if( log.level > 2 ) + log.println( "setupCount is not zero: " + setupCount ); + } + + return bufferIndex - start; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + pad = pad1 = 0; + int n; + + if( parameterCount > 0 ) { + bufferIndex += pad = parameterOffset - ( bufferIndex - headerStart ); + System.arraycopy( buffer, bufferIndex, txn_buf, + bufParameterStart + parameterDisplacement, parameterCount ); + bufferIndex += parameterCount; + } + if( dataCount > 0 ) { + bufferIndex += pad1 = dataOffset - ( bufferIndex - headerStart ); + System.arraycopy( buffer, bufferIndex, txn_buf, + bufDataStart + dataDisplacement, dataCount ); + bufferIndex += dataCount; + } + + /* Check to see if the entire transaction has been + * read. If so call the read methods. + */ + + if( !parametersDone && + ( parameterDisplacement + parameterCount ) == totalParameterCount) { + parametersDone = true; + } + + if( !dataDone && ( dataDisplacement + dataCount ) == totalDataCount) { + dataDone = true; + } + + if( parametersDone && dataDone ) { + hasMore = false; + readParametersWireFormat( txn_buf, bufParameterStart, totalParameterCount ); + readDataWireFormat( txn_buf, bufDataStart, totalDataCount ); + } + + return pad + parameterCount + pad1 + dataCount; + } + + abstract int writeSetupWireFormat( byte[] dst, int dstIndex ); + abstract int writeParametersWireFormat( byte[] dst, int dstIndex ); + abstract int writeDataWireFormat( byte[] dst, int dstIndex ); + abstract int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ); + abstract int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ); + abstract int readDataWireFormat( byte[] buffer, int bufferIndex, int len ); + + public String toString() { + return new String( super.toString() + + ",totalParameterCount=" + totalParameterCount + + ",totalDataCount=" + totalDataCount + + ",parameterCount=" + parameterCount + + ",parameterOffset=" + parameterOffset + + ",parameterDisplacement=" + parameterDisplacement + + ",dataCount=" + dataCount + + ",dataOffset=" + dataOffset + + ",dataDisplacement=" + dataDisplacement + + ",setupCount=" + setupCount + + ",pad=" + pad + + ",pad1=" + pad1 ); + } +} diff --git a/src/jcifs/smb/SmbComTreeConnectAndX.java b/src/jcifs/smb/SmbComTreeConnectAndX.java new file mode 100644 index 0000000..0650d4b --- /dev/null +++ b/src/jcifs/smb/SmbComTreeConnectAndX.java @@ -0,0 +1,185 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.Config; +import java.io.UnsupportedEncodingException; +import jcifs.util.Hexdump; + +class SmbComTreeConnectAndX extends AndXServerMessageBlock { + + private static final boolean DISABLE_PLAIN_TEXT_PASSWORDS = + Config.getBoolean( "jcifs.smb.client.disablePlainTextPasswords", true ); + + private SmbSession session; + private boolean disconnectTid = false; + private String service; + private byte[] password; + private int passwordLength; + String path; + + /* batchLimits indecies + * + * 0 = SMB_COM_CHECK_DIRECTORY + * 2 = SMB_COM_CREATE_DIRECTORY + * 3 = SMB_COM_DELETE + * 4 = SMB_COM_DELETE_DIRECTORY + * 5 = SMB_COM_OPEN_ANDX + * 6 = SMB_COM_RENAME + * 7 = SMB_COM_TRANSACTION + * 8 = SMB_COM_QUERY_INFORMATION + */ + + /* All batch limits are single batch only until further notice + */ + + private static byte[] batchLimits = { + 1, 1, 1, 1, 1, 1, 1, 1, 0 + }; + + static { + String s; + + if(( s = Config.getProperty( "jcifs.smb.client.TreeConnectAndX.CheckDirectory" )) != null ) { + batchLimits[0] = Byte.parseByte( s ); + } + if(( s = Config.getProperty( "jcifs.smb.client.TreeConnectAndX.CreateDirectory" )) != null ) { + batchLimits[2] = Byte.parseByte( s ); + } + if(( s = Config.getProperty( "jcifs.smb.client.TreeConnectAndX.Delete" )) != null ) { + batchLimits[3] = Byte.parseByte( s ); + } + if(( s = Config.getProperty( "jcifs.smb.client.TreeConnectAndX.DeleteDirectory" )) != null ) { + batchLimits[4] = Byte.parseByte( s ); + } + if(( s = Config.getProperty( "jcifs.smb.client.TreeConnectAndX.OpenAndX" )) != null ) { + batchLimits[5] = Byte.parseByte( s ); + } + if(( s = Config.getProperty( "jcifs.smb.client.TreeConnectAndX.Rename" )) != null ) { + batchLimits[6] = Byte.parseByte( s ); + } + if(( s = Config.getProperty( "jcifs.smb.client.TreeConnectAndX.Transaction" )) != null ) { + batchLimits[7] = Byte.parseByte( s ); + } + if(( s = Config.getProperty( "jcifs.smb.client.TreeConnectAndX.QueryInformation" )) != null ) { + batchLimits[8] = Byte.parseByte( s ); + } + } + + SmbComTreeConnectAndX( SmbSession session, String path, + String service, ServerMessageBlock andx ) { + super( andx ); + this.session = session; + this.path = path; + this.service = service; + command = SMB_COM_TREE_CONNECT_ANDX; + } + + int getBatchLimit( byte command ) { + int c = (int)( command & 0xFF ); + // why isn't this just return batchLimits[c]? + switch( c ) { + case SMB_COM_CHECK_DIRECTORY: + return batchLimits[0]; + case SMB_COM_CREATE_DIRECTORY: + return batchLimits[2]; + case SMB_COM_DELETE: + return batchLimits[3]; + case SMB_COM_DELETE_DIRECTORY: + return batchLimits[4]; + case SMB_COM_OPEN_ANDX: + return batchLimits[5]; + case SMB_COM_RENAME: + return batchLimits[6]; + case SMB_COM_TRANSACTION: + return batchLimits[7]; + case SMB_COM_QUERY_INFORMATION: + return batchLimits[8]; + } + return 0; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + + if( session.transport.server.security == SECURITY_SHARE && + ( session.auth.hashesExternal || + session.auth.password.length() > 0 )) { + + if( session.transport.server.encryptedPasswords ) { + // encrypted + password = session.auth.getAnsiHash( session.transport.server.encryptionKey ); + passwordLength = password.length; + } else if( DISABLE_PLAIN_TEXT_PASSWORDS ) { + throw new RuntimeException( "Plain text passwords are disabled" ); + } else { + // plain text + password = new byte[(session.auth.password.length() + 1) * 2]; + passwordLength = writeString( session.auth.password, password, 0 ); + } + } else { + // no password in tree connect + passwordLength = 1; + } + + dst[dstIndex++] = disconnectTid ? (byte)0x01 : (byte)0x00; + dst[dstIndex++] = (byte)0x00; + writeInt2( passwordLength, dst, dstIndex ); + return 4; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + if( session.transport.server.security == SECURITY_SHARE && + ( session.auth.hashesExternal || + session.auth.password.length() > 0 )) { + System.arraycopy( password, 0, dst, dstIndex, passwordLength ); + dstIndex += passwordLength; + } else { + // no password in tree connect + dst[dstIndex++] = (byte)0x00; + } + dstIndex += writeString( path, dst, dstIndex ); + try { + System.arraycopy( service.getBytes( "ASCII" ), 0, dst, dstIndex, service.length() ); + } catch( UnsupportedEncodingException uee ) { + return 0; + } + dstIndex += service.length(); + dst[dstIndex++] = (byte)'\0'; + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + String result = new String( "SmbComTreeConnectAndX[" + + super.toString() + + ",disconnectTid=" + disconnectTid + + ",passwordLength=" + passwordLength + + ",password=" + Hexdump.toHexString( password, passwordLength, 0 ) + + ",path=" + path + + ",service=" + service + "]" ); + return result; + } +} + diff --git a/src/jcifs/smb/SmbComTreeConnectAndXResponse.java b/src/jcifs/smb/SmbComTreeConnectAndXResponse.java new file mode 100644 index 0000000..6351482 --- /dev/null +++ b/src/jcifs/smb/SmbComTreeConnectAndXResponse.java @@ -0,0 +1,77 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.UnsupportedEncodingException; + +class SmbComTreeConnectAndXResponse extends AndXServerMessageBlock { + + private static final int SMB_SUPPORT_SEARCH_BITS = 0x0001; + private static final int SMB_SHARE_IS_IN_DFS = 0x0002; + + boolean supportSearchBits, shareIsInDfs; + String service, nativeFileSystem = ""; + + SmbComTreeConnectAndXResponse( ServerMessageBlock andx ) { + super( andx ); + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + supportSearchBits = ( buffer[bufferIndex] & SMB_SUPPORT_SEARCH_BITS ) == SMB_SUPPORT_SEARCH_BITS; + shareIsInDfs = ( buffer[bufferIndex] & SMB_SHARE_IS_IN_DFS ) == SMB_SHARE_IS_IN_DFS; + return 2; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + int len = readStringLength( buffer, bufferIndex, 32 ); + try { + service = new String( buffer, bufferIndex, len, "ASCII" ); + } catch( UnsupportedEncodingException uee ) { + return 0; + } + bufferIndex += len + 1; + // win98 observed not returning nativeFileSystem +/* Problems here with iSeries returning ASCII even though useUnicode = true + * Fortunately we don't really need nativeFileSystem for anything. + if( byteCount > bufferIndex - start ) { + nativeFileSystem = readString( buffer, bufferIndex ); + bufferIndex += stringWireLength( nativeFileSystem, bufferIndex ); + } +*/ + + return bufferIndex - start; + } + public String toString() { + String result = new String( "SmbComTreeConnectAndXResponse[" + + super.toString() + + ",supportSearchBits=" + supportSearchBits + + ",shareIsInDfs=" + shareIsInDfs + + ",service=" + service + + ",nativeFileSystem=" + nativeFileSystem + "]" ); + return result; + } +} + diff --git a/src/jcifs/smb/SmbComTreeDisconnect.java b/src/jcifs/smb/SmbComTreeDisconnect.java new file mode 100644 index 0000000..584a407 --- /dev/null +++ b/src/jcifs/smb/SmbComTreeDisconnect.java @@ -0,0 +1,43 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComTreeDisconnect extends ServerMessageBlock { + + SmbComTreeDisconnect() { + command = SMB_COM_TREE_DISCONNECT; + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComTreeDisconnect[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComWrite.java b/src/jcifs/smb/SmbComWrite.java new file mode 100644 index 0000000..79b3248 --- /dev/null +++ b/src/jcifs/smb/SmbComWrite.java @@ -0,0 +1,97 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.Config; + +class SmbComWrite extends ServerMessageBlock { + + private int fid, + count, + offset, + remaining, + off; + private byte[] b; + + SmbComWrite() { + super(); + command = SMB_COM_WRITE; + } + SmbComWrite( int fid, int offset, int remaining, byte[] b, int off, int len ) { + this.fid = fid; + this.count = len; + this.offset = offset; + this.remaining = remaining; + this.b = b; + this.off = off; + command = SMB_COM_WRITE; + } + + void setParam( int fid, long offset, int remaining, + byte[] b, int off, int len ) { + this.fid = fid; + this.offset = (int)(offset & 0xFFFFFFFFL); + this.remaining = remaining; + this.b = b; + this.off = off; + count = len; + digest = null; /* otherwise recycled commands + * like writeandx will choke if session + * closes in between */ + } + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( fid, dst, dstIndex ); + dstIndex += 2; + writeInt2( count, dst, dstIndex ); + dstIndex += 2; + writeInt4( offset, dst, dstIndex ); + dstIndex += 4; + writeInt2( remaining, dst, dstIndex ); + dstIndex += 2; + + return dstIndex - start; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + dst[dstIndex++] = (byte)0x01; /* BufferFormat */ + writeInt2( count, dst, dstIndex ); /* DataLength? */ + dstIndex += 2; + System.arraycopy( b, off, dst, dstIndex, count ); + dstIndex += count; + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComWrite[" + + super.toString() + + ",fid=" + fid + + ",count=" + count + + ",offset=" + offset + + ",remaining=" + remaining + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComWriteAndX.java b/src/jcifs/smb/SmbComWriteAndX.java new file mode 100644 index 0000000..971ce12 --- /dev/null +++ b/src/jcifs/smb/SmbComWriteAndX.java @@ -0,0 +1,138 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.Config; +import jcifs.util.*; + +class SmbComWriteAndX extends AndXServerMessageBlock { + + private static final int READ_ANDX_BATCH_LIMIT = + Config.getInt( "jcifs.smb.client.WriteAndX.ReadAndX", 1 ); + private static final int CLOSE_BATCH_LIMIT = + Config.getInt( "jcifs.smb.client.WriteAndX.Close", 1 ); + + private int fid, + remaining, + dataLength, + dataOffset, + off; + private byte[] b; + private long offset; + +private int pad; + + int writeMode; + + SmbComWriteAndX() { + super( null ); + command = SMB_COM_WRITE_ANDX; + } + SmbComWriteAndX( int fid, long offset, int remaining, + byte[] b, int off, int len, ServerMessageBlock andx ) { + super( andx ); + this.fid = fid; + this.offset = offset; + this.remaining = remaining; + this.b = b; + this.off = off; + dataLength = len; + command = SMB_COM_WRITE_ANDX; + } + + void setParam( int fid, long offset, int remaining, + byte[] b, int off, int len ) { + this.fid = fid; + this.offset = offset; + this.remaining = remaining; + this.b = b; + this.off = off; + dataLength = len; + digest = null; /* otherwise recycled commands + * like writeandx will choke if session + * closes in between */ + } + int getBatchLimit( byte command ) { + if( command == SMB_COM_READ_ANDX ) { + return READ_ANDX_BATCH_LIMIT; + } + if( command == SMB_COM_CLOSE ) { + return CLOSE_BATCH_LIMIT; + } + return 0; + } + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + dataOffset = (dstIndex - headerStart) + 26; // 26 = off from here to pad + +pad = ( dataOffset - headerStart ) % 4; +pad = pad == 0 ? 0 : 4 - pad; +dataOffset += pad; + + writeInt2( fid, dst, dstIndex ); + dstIndex += 2; + writeInt4( offset, dst, dstIndex ); + dstIndex += 4; + for( int i = 0; i < 4; i++ ) { + dst[dstIndex++] = (byte)0xFF; + } + writeInt2( writeMode, dst, dstIndex ); + dstIndex += 2; + writeInt2( remaining, dst, dstIndex ); + dstIndex += 2; + dst[dstIndex++] = (byte)0x00; + dst[dstIndex++] = (byte)0x00; + writeInt2( dataLength, dst, dstIndex ); + dstIndex += 2; + writeInt2( dataOffset, dst, dstIndex ); + dstIndex += 2; + writeInt4( offset >> 32, dst, dstIndex ); + dstIndex += 4; + + return dstIndex - start; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + +while( pad-- > 0 ) { + dst[dstIndex++] = (byte)0xEE; +} + System.arraycopy( b, off, dst, dstIndex, dataLength ); + dstIndex += dataLength; + + return dstIndex - start; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComWriteAndX[" + + super.toString() + + ",fid=" + fid + + ",offset=" + offset + + ",writeMode=" + writeMode + + ",remaining=" + remaining + + ",dataLength=" + dataLength + + ",dataOffset=" + dataOffset + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComWriteAndXResponse.java b/src/jcifs/smb/SmbComWriteAndXResponse.java new file mode 100644 index 0000000..6e8007b --- /dev/null +++ b/src/jcifs/smb/SmbComWriteAndXResponse.java @@ -0,0 +1,46 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComWriteAndXResponse extends AndXServerMessageBlock { + + long count; + + SmbComWriteAndXResponse() { + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + count = readInt2( buffer, bufferIndex ) & 0xFFFFL; + return 8; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComWriteAndXResponse[" + + super.toString() + + ",count=" + count + "]" ); + } +} diff --git a/src/jcifs/smb/SmbComWriteResponse.java b/src/jcifs/smb/SmbComWriteResponse.java new file mode 100644 index 0000000..fb24307 --- /dev/null +++ b/src/jcifs/smb/SmbComWriteResponse.java @@ -0,0 +1,46 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class SmbComWriteResponse extends ServerMessageBlock { + + long count; + + SmbComWriteResponse() { + } + + int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeBytesWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) { + count = readInt2( buffer, bufferIndex ) & 0xFFFFL; + return 8; + } + int readBytesWireFormat( byte[] buffer, int bufferIndex ) { + return 0; + } + public String toString() { + return new String( "SmbComWriteResponse[" + + super.toString() + + ",count=" + count + "]" ); + } +} diff --git a/src/jcifs/smb/SmbConstants.java b/src/jcifs/smb/SmbConstants.java new file mode 100644 index 0000000..2c5ad79 --- /dev/null +++ b/src/jcifs/smb/SmbConstants.java @@ -0,0 +1,161 @@ +package jcifs.smb; + +import java.util.LinkedList; +import java.net.InetAddress; +import java.util.TimeZone; +import jcifs.Config; + +interface SmbConstants { + + static final int DEFAULT_PORT = 445; + + static final int DEFAULT_MAX_MPX_COUNT = 10; + static final int DEFAULT_RESPONSE_TIMEOUT = 30000; + static final int DEFAULT_SO_TIMEOUT = 35000; + static final int DEFAULT_RCV_BUF_SIZE = 60416; + static final int DEFAULT_SND_BUF_SIZE = 16644; + static final int DEFAULT_SSN_LIMIT = 250; + + static final InetAddress LADDR = Config.getLocalHost(); + static final int LPORT = Config.getInt( "jcifs.smb.client.lport", 0 ); + static final int MAX_MPX_COUNT = Config.getInt( "jcifs.smb.client.maxMpxCount", DEFAULT_MAX_MPX_COUNT ); + static final int SND_BUF_SIZE = Config.getInt( "jcifs.smb.client.snd_buf_size", DEFAULT_SND_BUF_SIZE ); + static final int RCV_BUF_SIZE = Config.getInt( "jcifs.smb.client.rcv_buf_size", DEFAULT_RCV_BUF_SIZE ); + static final boolean USE_UNICODE = Config.getBoolean( "jcifs.smb.client.useUnicode", true ); + static final boolean FORCE_UNICODE = Config.getBoolean( "jcifs.smb.client.useUnicode", false ); + static final boolean USE_NTSTATUS = Config.getBoolean( "jcifs.smb.client.useNtStatus", true ); + static final boolean SIGNPREF = Config.getBoolean("jcifs.smb.client.signingPreferred", false ); + static final boolean USE_NTSMBS = Config.getBoolean( "jcifs.smb.client.useNTSmbs", true ); + static final boolean USE_EXTSEC = Config.getBoolean( "jcifs.smb.client.useExtendedSecurity", true ); + + static final String NETBIOS_HOSTNAME = Config.getProperty( "jcifs.netbios.hostname", null ); + static final int LM_COMPATIBILITY = Config.getInt( "jcifs.smb.lmCompatibility", 3); + + static final int FLAGS_NONE = 0x00; + static final int FLAGS_LOCK_AND_READ_WRITE_AND_UNLOCK = 0x01; + static final int FLAGS_RECEIVE_BUFFER_POSTED = 0x02; + static final int FLAGS_PATH_NAMES_CASELESS = 0x08; + static final int FLAGS_PATH_NAMES_CANONICALIZED = 0x10; + static final int FLAGS_OPLOCK_REQUESTED_OR_GRANTED = 0x20; + static final int FLAGS_NOTIFY_OF_MODIFY_ACTION = 0x40; + static final int FLAGS_RESPONSE = 0x80; + + static final int FLAGS2_NONE = 0x0000; + static final int FLAGS2_LONG_FILENAMES = 0x0001; + static final int FLAGS2_EXTENDED_ATTRIBUTES = 0x0002; + static final int FLAGS2_SECURITY_SIGNATURES = 0x0004; + static final int FLAGS2_EXTENDED_SECURITY_NEGOTIATION = 0x0800; + static final int FLAGS2_RESOLVE_PATHS_IN_DFS = 0x1000; + static final int FLAGS2_PERMIT_READ_IF_EXECUTE_PERM = 0x2000; + static final int FLAGS2_STATUS32 = 0x4000; + static final int FLAGS2_UNICODE = 0x8000; + + static final int CAP_NONE = 0x0000; + static final int CAP_RAW_MODE = 0x0001; + static final int CAP_MPX_MODE = 0x0002; + static final int CAP_UNICODE = 0x0004; + static final int CAP_LARGE_FILES = 0x0008; + static final int CAP_NT_SMBS = 0x0010; + static final int CAP_RPC_REMOTE_APIS = 0x0020; + static final int CAP_STATUS32 = 0x0040; + static final int CAP_LEVEL_II_OPLOCKS = 0x0080; + static final int CAP_LOCK_AND_READ = 0x0100; + static final int CAP_NT_FIND = 0x0200; + static final int CAP_DFS = 0x1000; + static final int CAP_EXTENDED_SECURITY = 0x80000000; + + // file attribute encoding + static final int ATTR_READONLY = 0x01; + static final int ATTR_HIDDEN = 0x02; + static final int ATTR_SYSTEM = 0x04; + static final int ATTR_VOLUME = 0x08; + static final int ATTR_DIRECTORY = 0x10; + static final int ATTR_ARCHIVE = 0x20; + + // extended file attribute encoding(others same as above) + static final int ATTR_COMPRESSED = 0x800; + static final int ATTR_NORMAL = 0x080; + static final int ATTR_TEMPORARY = 0x100; + + // access mask encoding + static final int FILE_READ_DATA = 0x00000001; // 1 + static final int FILE_WRITE_DATA = 0x00000002; // 2 + static final int FILE_APPEND_DATA = 0x00000004; // 3 + static final int FILE_READ_EA = 0x00000008; // 4 + static final int FILE_WRITE_EA = 0x00000010; // 5 + static final int FILE_EXECUTE = 0x00000020; // 6 + static final int FILE_DELETE = 0x00000040; // 7 + static final int FILE_READ_ATTRIBUTES = 0x00000080; // 8 + static final int FILE_WRITE_ATTRIBUTES = 0x00000100; // 9 + static final int DELETE = 0x00010000; // 16 + static final int READ_CONTROL = 0x00020000; // 17 + static final int WRITE_DAC = 0x00040000; // 18 + static final int WRITE_OWNER = 0x00080000; // 19 + static final int SYNCHRONIZE = 0x00100000; // 20 + static final int GENERIC_ALL = 0x10000000; // 28 + static final int GENERIC_EXECUTE = 0x20000000; // 29 + static final int GENERIC_WRITE = 0x40000000; // 30 + static final int GENERIC_READ = 0x80000000; // 31 + + + // flags for move and copy + static final int FLAGS_TARGET_MUST_BE_FILE = 0x0001; + static final int FLAGS_TARGET_MUST_BE_DIRECTORY = 0x0002; + static final int FLAGS_COPY_TARGET_MODE_ASCII = 0x0004; + static final int FLAGS_COPY_SOURCE_MODE_ASCII = 0x0008; + static final int FLAGS_VERIFY_ALL_WRITES = 0x0010; + static final int FLAGS_TREE_COPY = 0x0020; + + // open function + static final int OPEN_FUNCTION_FAIL_IF_EXISTS = 0x0000; + static final int OPEN_FUNCTION_OVERWRITE_IF_EXISTS = 0x0020; + + static final int PID = (int)( Math.random() * 65536d ); + + static final int SECURITY_SHARE = 0x00; + static final int SECURITY_USER = 0x01; + + static final int CMD_OFFSET = 4; + static final int ERROR_CODE_OFFSET = 5; + static final int FLAGS_OFFSET = 9; + static final int SIGNATURE_OFFSET = 14; + static final int TID_OFFSET = 24; + static final int HEADER_LENGTH = 32; + + static final long MILLISECONDS_BETWEEN_1970_AND_1601 = 11644473600000L; + static final TimeZone TZ = TimeZone.getDefault(); + + static final boolean USE_BATCHING = Config.getBoolean( "jcifs.smb.client.useBatching", true ); + static final String OEM_ENCODING = Config.getProperty( "jcifs.encoding", Config.DEFAULT_OEM_ENCODING ); + static final String UNI_ENCODING = "UTF-16LE"; + static final int DEFAULT_FLAGS2 = + FLAGS2_LONG_FILENAMES | + FLAGS2_EXTENDED_ATTRIBUTES | + ( USE_EXTSEC ? FLAGS2_EXTENDED_SECURITY_NEGOTIATION : 0 ) | + ( SIGNPREF ? FLAGS2_SECURITY_SIGNATURES : 0 ) | + ( USE_NTSTATUS ? FLAGS2_STATUS32 : 0 ) | + ( USE_UNICODE ? FLAGS2_UNICODE : 0 ); + static final int DEFAULT_CAPABILITIES = + ( USE_NTSMBS ? CAP_NT_SMBS : 0 ) | + ( USE_NTSTATUS ? CAP_STATUS32 : 0 ) | + ( USE_UNICODE ? CAP_UNICODE : 0 ) | + CAP_DFS; + static final int FLAGS2 = Config.getInt( "jcifs.smb.client.flags2", DEFAULT_FLAGS2 ); + static final int CAPABILITIES = Config.getInt( "jcifs.smb.client.capabilities", DEFAULT_CAPABILITIES ); + static final boolean TCP_NODELAY = Config.getBoolean( "jcifs.smb.client.tcpNoDelay", false ); + static final int RESPONSE_TIMEOUT = + Config.getInt( "jcifs.smb.client.responseTimeout", DEFAULT_RESPONSE_TIMEOUT ); + + static final LinkedList CONNECTIONS = new LinkedList(); + + static final int SSN_LIMIT = + Config.getInt( "jcifs.smb.client.ssnLimit", DEFAULT_SSN_LIMIT ); + static final int SO_TIMEOUT = + Config.getInt( "jcifs.smb.client.soTimeout", DEFAULT_SO_TIMEOUT ); + static final String NATIVE_OS = + Config.getProperty( "jcifs.smb.client.nativeOs", System.getProperty( "os.name" )); + static final String NATIVE_LANMAN = + Config.getProperty( "jcifs.smb.client.nativeLanMan", "jCIFS" ); + static final int VC_NUMBER = 1; + static final SmbTransport NULL_TRANSPORT = new SmbTransport( null, 0, null, 0 ); +} diff --git a/src/jcifs/smb/SmbException.java b/src/jcifs/smb/SmbException.java new file mode 100644 index 0000000..11b7ce8 --- /dev/null +++ b/src/jcifs/smb/SmbException.java @@ -0,0 +1,169 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.PrintWriter; +import jcifs.util.Hexdump; + +/** + * There are hundreds of error codes that may be returned by a CIFS + * server. Rather than represent each with it's own Exception + * class, this class represents all of them. For many of the popular + * error codes, constants and text messages like "The device is not ready" + * are provided. + *

+ * The jCIFS client maps DOS error codes to NTSTATUS codes. This means that + * the user may recieve a different error from a legacy server than that of + * a newer varient such as Windows NT and above. If you should encounter + * such a case, please report it to jcifs at samba dot org and we will + * change the mapping. + */ + +public class SmbException extends IOException implements NtStatus, DosError, WinError { + + static String getMessageByCode( int errcode ) { + /* Note there's a signedness error here because 0xC0000000 based values are + * negative so it with NT_STATUS_SUCCESS (0) the binary search will not be + * performed properly. The effect is that the code at index 1 is never found + * (NT_STATUS_UNSUCCESSFUL). So here we factor out NT_STATUS_SUCCESS + * as a special case (which it is). + */ + if (errcode == 0) { + return "NT_STATUS_SUCCESS"; + } + if(( errcode & 0xC0000000 ) == 0xC0000000 ) { + int min = 1; /* Don't include NT_STATUS_SUCCESS */ + int max = NT_STATUS_CODES.length - 1; + + while( max >= min ) { + int mid = (min + max) / 2; + + if( errcode > NT_STATUS_CODES[mid] ) { + min = mid + 1; + } else if( errcode < NT_STATUS_CODES[mid] ) { + max = mid - 1; + } else { + return NT_STATUS_MESSAGES[mid]; + } + } + } else { + int min = 0; + int max = DOS_ERROR_CODES.length - 1; + + while( max >= min ) { + int mid = (min + max) / 2; + + if( errcode > DOS_ERROR_CODES[mid][0] ) { + min = mid + 1; + } else if( errcode < DOS_ERROR_CODES[mid][0] ) { + max = mid - 1; + } else { + return DOS_ERROR_MESSAGES[mid]; + } + } + } + + return "0x" + Hexdump.toHexString( errcode, 8 ); + } + static int getStatusByCode( int errcode ) { + if(( errcode & 0xC0000000 ) != 0 ) { + return errcode; + } else { + int min = 0; + int max = DOS_ERROR_CODES.length - 1; + + while( max >= min ) { + int mid = (min + max) / 2; + + if( errcode > DOS_ERROR_CODES[mid][0] ) { + min = mid + 1; + } else if( errcode < DOS_ERROR_CODES[mid][0] ) { + max = mid - 1; + } else { + return DOS_ERROR_CODES[mid][1]; + } + } + } + + return NT_STATUS_UNSUCCESSFUL; + } + static String getMessageByWinerrCode( int errcode ) { + int min = 0; + int max = WINERR_CODES.length - 1; + + while( max >= min ) { + int mid = (min + max) / 2; + + if( errcode > WINERR_CODES[mid] ) { + min = mid + 1; + } else if( errcode < WINERR_CODES[mid] ) { + max = mid - 1; + } else { + return WINERR_MESSAGES[mid]; + } + } + + return errcode + ""; + } + + + private int status; + private Throwable rootCause; + + SmbException() { + } + SmbException( int errcode, Throwable rootCause ) { + super( getMessageByCode( errcode )); + status = getStatusByCode( errcode ); + this.rootCause = rootCause; + } + SmbException( String msg ) { + super( msg ); + status = NT_STATUS_UNSUCCESSFUL; + } + SmbException( String msg, Throwable rootCause ) { + super( msg ); + this.rootCause = rootCause; + status = NT_STATUS_UNSUCCESSFUL; + } + public SmbException( int errcode, boolean winerr ) { + super( winerr ? getMessageByWinerrCode( errcode ) : getMessageByCode( errcode )); + status = winerr ? errcode : getStatusByCode( errcode ); + } + + public int getNtStatus() { + return status; + } + public Throwable getRootCause() { + return rootCause; + } + public String toString() { + if( rootCause != null ) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter( sw ); + rootCause.printStackTrace( pw ); + return super.toString() + "\n" + sw; + } else { + return super.toString(); + } + } +} + diff --git a/src/jcifs/smb/SmbFile.java b/src/jcifs/smb/SmbFile.java new file mode 100644 index 0000000..77e8e1f --- /dev/null +++ b/src/jcifs/smb/SmbFile.java @@ -0,0 +1,2967 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.net.URLConnection; +import java.net.URL; +import java.net.MalformedURLException; +import java.net.UnknownHostException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.security.Principal; +import jcifs.Config; +import jcifs.util.LogStream; +import jcifs.UniAddress; +import jcifs.netbios.NbtAddress; +import jcifs.dcerpc.*; +import jcifs.dcerpc.msrpc.*; + +import java.util.Date; + +/** + * This class represents a resource on an SMB network. Mainly these + * resources are files and directories however an SmbFile + * may also refer to servers and workgroups. If the resource is a file or + * directory the methods of SmbFile follow the behavior of + * the well known {@link java.io.File} class. One fundamental difference + * is the usage of a URL scheme [1] to specify the target file or + * directory. SmbFile URLs have the following syntax: + * + *

+ *     smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?[param=value[param2=value2[...]]]
+ * 
+ * + * This example: + * + *
+ *     smb://storage15/public/foo.txt
+ * 
+ * + * would reference the file foo.txt in the share + * public on the server storage15. In addition + * to referencing files and directories, jCIFS can also address servers, + * and workgroups. + *

+ * Important: all SMB URLs that represent + * workgroups, servers, shares, or directories require a trailing slash '/'. + * + *

+ * When using the java.net.URL class with + * 'smb://' URLs it is necessary to first call the static + * jcifs.Config.registerSmbURLHandler(); method. This is required + * to register the SMB protocol handler. + *

+ * The userinfo component of the SMB URL (domain;user:pass) must + * be URL encoded if it contains reserved characters. According to RFC 2396 + * these characters are non US-ASCII characters and most meta characters + * however jCIFS will work correctly with anything but '@' which is used + * to delimit the userinfo component from the server and '%' which is the + * URL escape character itself. + *

+ * The server + * component may a traditional NetBIOS name, a DNS name, or IP + * address. These name resolution mechanisms and their resolution order + * can be changed (See Setting Name + * Resolution Properties). The servername and path components are + * not case sensitive but the domain, username, and password components + * are. It is also likely that properties must be specified for jcifs + * to function (See Setting + * JCIFS Properties). Here are some examples of SMB URLs with brief + * descriptions of what they do: + * + *

[1] This URL scheme is based largely on the SMB + * Filesharing URL Scheme IETF draft. + * + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
SMB URL Examples
URLDescription
smb://users-nyc;miallen:mypass@angus/tmp/ + * This URL references a share called tmp on the server + * angus as user miallen who's password is + * mypass. + *
+ * smb://Administrator:P%40ss@msmith1/c/WINDOWS/Desktop/foo.txt + * A relativly sophisticated example that references a file + * msmith1's desktop as user Administrator. Notice the '@' is URL encoded with the '%40' hexcode escape. + *
smb://angus/ + * This references only a server. The behavior of some methods is different + * in this context(e.g. you cannot delete a server) however + * as you might expect the list method will list the available + * shares on this server. + *
smb://myworkgroup/ + * This syntactically is identical to the above example. However if + * myworkgroup happends to be a workgroup(which is indeed + * suggested by the name) the list method will return + * a list of servers that have registered themselves as members of + * myworkgroup. + *
smb:// + * Just as smb://server/ lists shares and + * smb://workgroup/ lists servers, the smb:// + * URL lists all available workgroups on a netbios LAN. Again, + * in this context many methods are not valid and return default + * values(e.g. isHidden will always return false). + *
smb://angus.foo.net/d/jcifs/pipes.doc + * The server name may also be a DNS name as it is in this example. See + * Setting Name Resolution Properties + * for details. + *
smb://192.168.1.15/ADMIN$/ + * The server name may also be an IP address. See Setting Name Resolution Properties + * for details. + *
+ * smb://domain;username:password@server/share/path/to/file.txt + * A prototypical example that uses all the fields. + *
smb://myworkgroup/angus/ <-- ILLEGAL + * Despite the hierarchial relationship between workgroups, servers, and + * filesystems this example is not valid. + *
+ * smb://server/share/path/to/dir <-- ILLEGAL + * URLs that represent workgroups, servers, shares, or directories require a trailing slash '/'. + *
+ * smb://MYGROUP/?SERVER=192.168.10.15 + * SMB URLs support some query string parameters. In this example + * the SERVER parameter is used to override the + * server name service lookup to contact the server 192.168.10.15 + * (presumably known to be a master + * browser) for the server list in workgroup MYGROUP. + *
+ * + *

A second constructor argument may be specified to augment the URL + * for better programmatic control when processing many files under + * a common base. This is slightly different from the corresponding + * java.io.File usage; a '/' at the beginning of the second + * parameter will still use the server component of the first parameter. The + * examples below illustrate the resulting URLs when this second contructor + * argument is used. + * + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
+ * Examples Of SMB URLs When Augmented With A Second Constructor Parameter
+ * First ParameterSecond ParameterResult
+ * smb://host/share/a/b/ + * + * c/d/ + * + * smb://host/share/a/b/c/d/ + *
+ * smb://host/share/foo/bar/ + * + * /share2/zig/zag + * + * smb://host/share2/zig/zag + *
+ * smb://host/share/foo/bar/ + * + * ../zip/ + * + * smb://host/share/foo/zip/ + *
+ * smb://host/share/zig/zag + * + * smb://foo/bar/ + * + * smb://foo/bar/ + *
+ * smb://host/share/foo/ + * + * ../.././.././../foo/ + * + * smb://host/foo/ + *
+ * smb://host/share/zig/zag + * + * / + * + * smb://host/ + *
+ * smb://server/ + * + * ../ + * + * smb://server/ + *
+ * smb:// + * + * myworkgroup/ + * + * smb://myworkgroup/ + *
+ * smb://myworkgroup/ + * + * angus/ + * + * smb://myworkgroup/angus/ <-- ILLEGAL
(But if you first create an SmbFile with 'smb://workgroup/' and use and use it as the first parameter to a constructor that accepts it with a second String parameter jCIFS will factor out the 'workgroup'.) + *
+ * + *

Instances of the SmbFile class are immutable; that is, + * once created, the abstract pathname represented by an SmbFile object + * will never change. + * + * @see java.io.File + */ + +public class SmbFile extends URLConnection implements SmbConstants { + + static final int O_RDONLY = 0x01; + static final int O_WRONLY = 0x02; + static final int O_RDWR = 0x03; + static final int O_APPEND = 0x04; + + // Open Function Encoding + // create if the file does not exist + static final int O_CREAT = 0x0010; + // fail if the file exists + static final int O_EXCL = 0x0020; + // truncate if the file exists + static final int O_TRUNC = 0x0040; + + // share access +/** + * When specified as the shareAccess constructor parameter, + * other SMB clients (including other threads making calls into jCIFS) + * will not be permitted to access the target file and will receive "The + * file is being accessed by another process" message. + */ + public static final int FILE_NO_SHARE = 0x00; +/** + * When specified as the shareAccess constructor parameter, + * other SMB clients will be permitted to read from the target file while + * this file is open. This constant may be logically OR'd with other share + * access flags. + */ + public static final int FILE_SHARE_READ = 0x01; +/** + * When specified as the shareAccess constructor parameter, + * other SMB clients will be permitted to write to the target file while + * this file is open. This constant may be logically OR'd with other share + * access flags. + */ + public static final int FILE_SHARE_WRITE = 0x02; +/** + * When specified as the shareAccess constructor parameter, + * other SMB clients will be permitted to delete the target file while + * this file is open. This constant may be logically OR'd with other share + * access flags. + */ + public static final int FILE_SHARE_DELETE = 0x04; + + // file attribute encoding +/** + * A file with this bit on as returned by getAttributes() or set + * with setAttributes() will be read-only + */ + public static final int ATTR_READONLY = 0x01; +/** + * A file with this bit on as returned by getAttributes() or set + * with setAttributes() will be hidden + */ + public static final int ATTR_HIDDEN = 0x02; +/** + * A file with this bit on as returned by getAttributes() or set + * with setAttributes() will be a system file + */ + public static final int ATTR_SYSTEM = 0x04; +/** + * A file with this bit on as returned by getAttributes() is + * a volume + */ + public static final int ATTR_VOLUME = 0x08; +/** + * A file with this bit on as returned by getAttributes() is + * a directory + */ + public static final int ATTR_DIRECTORY = 0x10; +/** + * A file with this bit on as returned by getAttributes() or set + * with setAttributes() is an archived file + */ + public static final int ATTR_ARCHIVE = 0x20; + + // extended file attribute encoding(others same as above) + static final int ATTR_COMPRESSED = 0x800; + static final int ATTR_NORMAL = 0x080; + static final int ATTR_TEMPORARY = 0x100; + + static final int ATTR_GET_MASK = 0x7FFF; /* orig 0x7fff */ + static final int ATTR_SET_MASK = 0x30A7; /* orig 0x0027 */ + + static final int DEFAULT_ATTR_EXPIRATION_PERIOD = 5000; + + static final int HASH_DOT = ".".hashCode(); + static final int HASH_DOT_DOT = "..".hashCode(); + + static LogStream log = LogStream.getInstance(); + static long attrExpirationPeriod; + + static { + + try { + Class.forName( "jcifs.Config" ); + } catch( ClassNotFoundException cnfe ) { + cnfe.printStackTrace(); + } + attrExpirationPeriod = Config.getLong( "jcifs.smb.client.attrExpirationPeriod", DEFAULT_ATTR_EXPIRATION_PERIOD ); + dfs = new Dfs(); + } + + /** + * Returned by {@link #getType()} if the resource this SmbFile + * represents is a regular file or directory. + */ + public static final int TYPE_FILESYSTEM = 0x01; + /** + * Returned by {@link #getType()} if the resource this SmbFile + * represents is a workgroup. + */ + public static final int TYPE_WORKGROUP = 0x02; + /** + * Returned by {@link #getType()} if the resource this SmbFile + * represents is a server. + */ + public static final int TYPE_SERVER = 0x04; + /** + * Returned by {@link #getType()} if the resource this SmbFile + * represents is a share. + */ + public static final int TYPE_SHARE = 0x08; + /** + * Returned by {@link #getType()} if the resource this SmbFile + * represents is a named pipe. + */ + public static final int TYPE_NAMED_PIPE = 0x10; + /** + * Returned by {@link #getType()} if the resource this SmbFile + * represents is a printer. + */ + public static final int TYPE_PRINTER = 0x20; + /** + * Returned by {@link #getType()} if the resource this SmbFile + * represents is a communications device. + */ + public static final int TYPE_COMM = 0x40; + + + private String canon; // Initially null; set by getUncPath; dir must end with '/' + private String share; // Can be null + private long createTime; + private long lastModified; + private int attributes; + private long attrExpiration; + private long size; + private long sizeExpiration; + private boolean isExists; + private int shareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + private SmbComBlankResponse blank_resp = null; + private DfsReferral dfsReferral = null; // For getDfsPath() and getServerWithDfs() + + protected static Dfs dfs; + + NtlmPasswordAuthentication auth; // Cannot be null + SmbTree tree = null; // Initially null + String unc; // Initially null; set by getUncPath; never ends with '/' + int fid; // Initially 0; set by open() + int type; + boolean opened; + int tree_num; + +/** + * Constructs an SmbFile representing a resource on an SMB network such as + * a file or directory. See the description and examples of smb URLs above. + * + * @param url A URL string + * @throws MalformedURLException + * If the parent and child parameters + * do not follow the prescribed syntax + */ + + public SmbFile( String url ) throws MalformedURLException { + this( new URL( null, url, Handler.SMB_HANDLER )); + } + +/** + * Constructs an SmbFile representing a resource on an SMB network such + * as a file or directory. The second parameter is a relative path from + * the parent SmbFile. See the description above for examples + * of using the second name parameter. + * + * @param context A base SmbFile + * @param name A path string relative to the parent paremeter + * @throws MalformedURLException + * If the parent and child parameters + * do not follow the prescribed syntax + * @throws UnknownHostException + * If the server or workgroup of the context file cannot be determined + */ + + public SmbFile( SmbFile context, String name ) + throws MalformedURLException, UnknownHostException { + this( context.isWorkgroup0() ? + new URL( null, "smb://" + name, Handler.SMB_HANDLER ) : + new URL( context.url, name, Handler.SMB_HANDLER ), context.auth ); + } + +/** + * Constructs an SmbFile representing a resource on an SMB network such + * as a file or directory. The second parameter is a relative path from + * the parent. See the description above for examples of + * using the second chile parameter. + * + * @param context A URL string + * @param name A path string relative to the context paremeter + * @throws MalformedURLException + * If the context and name parameters + * do not follow the prescribed syntax + */ + + public SmbFile( String context, String name ) throws MalformedURLException { + this( new URL( new URL( null, context, Handler.SMB_HANDLER ), + name, Handler.SMB_HANDLER )); + } + +/** + * Constructs an SmbFile representing a resource on an SMB network such + * as a file or directory. + * + * @param url A URL string + * @param auth The credentials the client should use for authentication + * @throws MalformedURLException + * If the url parameter does not follow the prescribed syntax + */ + public SmbFile( String url, NtlmPasswordAuthentication auth ) + throws MalformedURLException { + this( new URL( null, url, Handler.SMB_HANDLER ), auth ); + } +/** + * Constructs an SmbFile representing a file on an SMB network. The + * shareAccess parameter controls what permissions other + * clients have when trying to access the same file while this instance + * is still open. This value is either FILE_NO_SHARE or any + * combination of FILE_SHARE_READ, FILE_SHARE_WRITE, + * and FILE_SHARE_DELETE logically OR'd together. + * + * @param url A URL string + * @param auth The credentials the client should use for authentication + * @param shareAccess Specifies what access other clients have while this file is open. + * @throws MalformedURLException + * If the url parameter does not follow the prescribed syntax + */ + public SmbFile( String url, NtlmPasswordAuthentication auth, int shareAccess ) + throws MalformedURLException { + this( new URL( null, url, Handler.SMB_HANDLER ), auth ); + if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) { + throw new RuntimeException( "Illegal shareAccess parameter" ); + } + this.shareAccess = shareAccess; + } +/** + * Constructs an SmbFile representing a resource on an SMB network such + * as a file or directory. The second parameter is a relative path from + * the context. See the description above for examples of + * using the second name parameter. + * + * @param context A URL string + * @param name A path string relative to the context paremeter + * @param auth The credentials the client should use for authentication + * @throws MalformedURLException + * If the context and name parameters + * do not follow the prescribed syntax + */ + public SmbFile( String context, String name, NtlmPasswordAuthentication auth ) + throws MalformedURLException { + this( new URL( new URL( null, context, Handler.SMB_HANDLER ), name, Handler.SMB_HANDLER ), auth ); + } +/** + * Constructs an SmbFile representing a resource on an SMB network such + * as a file or directory. The second parameter is a relative path from + * the context. See the description above for examples of + * using the second name parameter. The shareAccess + * parameter controls what permissions other clients have when trying + * to access the same file while this instance is still open. This + * value is either FILE_NO_SHARE or any combination + * of FILE_SHARE_READ, FILE_SHARE_WRITE, and + * FILE_SHARE_DELETE logically OR'd together. + * + * @param context A URL string + * @param name A path string relative to the context paremeter + * @param auth The credentials the client should use for authentication + * @param shareAccess Specifies what access other clients have while this file is open. + * @throws MalformedURLException + * If the context and name parameters + * do not follow the prescribed syntax + */ + public SmbFile( String context, String name, NtlmPasswordAuthentication auth, int shareAccess ) + throws MalformedURLException { + this( new URL( new URL( null, context, Handler.SMB_HANDLER ), name, Handler.SMB_HANDLER ), auth ); + if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) { + throw new RuntimeException( "Illegal shareAccess parameter" ); + } + this.shareAccess = shareAccess; + } +/** + * Constructs an SmbFile representing a resource on an SMB network such + * as a file or directory. The second parameter is a relative path from + * the context. See the description above for examples of + * using the second name parameter. The shareAccess + * parameter controls what permissions other clients have when trying + * to access the same file while this instance is still open. This + * value is either FILE_NO_SHARE or any combination + * of FILE_SHARE_READ, FILE_SHARE_WRITE, and + * FILE_SHARE_DELETE logically OR'd together. + * + * @param context A base SmbFile + * @param name A path string relative to the context file path + * @param shareAccess Specifies what access other clients have while this file is open. + * @throws MalformedURLException + * If the context and name parameters + * do not follow the prescribed syntax + */ + public SmbFile( SmbFile context, String name, int shareAccess ) + throws MalformedURLException, UnknownHostException { + this( context.isWorkgroup0() ? + new URL( null, "smb://" + name, Handler.SMB_HANDLER ) : + new URL( context.url, name, Handler.SMB_HANDLER ), context.auth ); + if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) { + throw new RuntimeException( "Illegal shareAccess parameter" ); + } + this.shareAccess = shareAccess; + } +/** + * Constructs an SmbFile representing a resource on an SMB network such + * as a file or directory from a URL object. + * + * @param url The URL of the target resource + */ + public SmbFile( URL url ) { + this( url, new NtlmPasswordAuthentication( url.getUserInfo() )); + } +/** + * Constructs an SmbFile representing a resource on an SMB network such + * as a file or directory from a URL object and an + * NtlmPasswordAuthentication object. + * + * @param url The URL of the target resource + * @param auth The credentials the client should use for authentication + */ + public SmbFile( URL url, NtlmPasswordAuthentication auth ) { + super( url ); + this.auth = auth == null ? new NtlmPasswordAuthentication( url.getUserInfo() ) : auth; + + getUncPath0(); + } + SmbFile( SmbFile context, String name, int type, + int attributes, long createTime, long lastModified, long size ) + throws MalformedURLException, UnknownHostException { + this( context.isWorkgroup0() ? + new URL( null, "smb://" + name + "/", Handler.SMB_HANDLER ) : + new URL( context.url, name + (( attributes & ATTR_DIRECTORY ) > 0 ? "/" : "" ))); + + /* why was this removed before? DFS? copyTo? Am I going around in circles? */ + auth = context.auth; + + + if( context.share != null ) { + this.tree = context.tree; + this.dfsReferral = context.dfsReferral; + } + int last = name.length() - 1; + if( name.charAt( last ) == '/' ) { + name = name.substring( 0, last ); + } + if( context.share == null ) { + this.unc = "\\"; + } else if( context.unc.equals( "\\" )) { + this.unc = '\\' + name; + } else { + this.unc = context.unc + '\\' + name; + } + /* why? am I going around in circles? + * this.type = type == TYPE_WORKGROUP ? 0 : type; + */ + this.type = type; + this.attributes = attributes; + this.createTime = createTime; + this.lastModified = lastModified; + this.size = size; + isExists = true; + + attrExpiration = sizeExpiration = + System.currentTimeMillis() + attrExpirationPeriod; + } + + private SmbComBlankResponse blank_resp() { + if( blank_resp == null ) { + blank_resp = new SmbComBlankResponse(); + } + return blank_resp; + } + void resolveDfs(ServerMessageBlock request) throws SmbException { + connect0(); + + DfsReferral dr = dfs.resolve( + tree.session.transport.tconHostName, + tree.share, + unc, + auth); + if (dr != null) { + String service = null; + + if (request != null) { + switch( request.command ) { + case ServerMessageBlock.SMB_COM_TRANSACTION: + case ServerMessageBlock.SMB_COM_TRANSACTION2: + switch( ((SmbComTransaction)request).subCommand & 0xFF ) { + case SmbComTransaction.TRANS2_GET_DFS_REFERRAL: + break; + default: + service = "A:"; + } + break; + default: + service = "A:"; + } + } + + DfsReferral start = dr; + SmbException se = null; + + do { + try { + if (log.level >= 2) + log.println("DFS redirect: " + dr); + + UniAddress addr = UniAddress.getByName(dr.server); + SmbTransport trans = SmbTransport.getSmbTransport(addr, url.getPort()); + /* This is a key point. This is where we set the "tree" of this file which + * is like changing the rug out from underneath our feet. + */ +/* Technically we should also try to authenticate here but that means doing the session setup and tree connect separately. For now a simple connect will at least tell us if the host is alive. That should be sufficient for 99% of the cases. We can revisit this again for 2.0. + */ + trans.connect(); + tree = trans.getSmbSession( auth ).getSmbTree( dr.share, service ); + + if (dr != start && dr.key != null) { + dr.map.put(dr.key, dr); + } + + se = null; + + break; + } catch (IOException ioe) { + if (ioe instanceof SmbException) { + se = (SmbException)ioe; + } else { + se = new SmbException(dr.server, ioe); + } + } + + dr = dr.next; + } while (dr != start); + + if (se != null) + throw se; + + if (log.level >= 3) + log.println( dr ); + + dfsReferral = dr; + if (dr.pathConsumed < 0) { + dr.pathConsumed = 0; + } else if (dr.pathConsumed > unc.length()) { + dr.pathConsumed = unc.length(); + } + String dunc = unc.substring(dr.pathConsumed); + if (dunc.equals("")) + dunc = "\\"; + if (!dr.path.equals("")) + dunc = "\\" + dr.path + dunc; + + unc = dunc; + if (request != null && + request.path != null && + request.path.endsWith("\\") && + dunc.endsWith("\\") == false) { + dunc += "\\"; + } + if (request != null) { + request.path = dunc; + request.flags2 |= ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS; + } + } else if (tree.inDomainDfs && + !(request instanceof NtTransQuerySecurityDesc) && + !(request instanceof SmbComClose) && + !(request instanceof SmbComFindClose2)) { + throw new SmbException(NtStatus.NT_STATUS_NOT_FOUND, false); + } else { + if (request != null) + request.flags2 &= ~ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS; + } + } + void send( ServerMessageBlock request, + ServerMessageBlock response ) throws SmbException { + for( ;; ) { + resolveDfs(request); + try { + tree.send( request, response ); + break; + } catch( DfsReferral dre ) { + if( dre.resolveHashes ) { + throw dre; + } + request.reset(); + } + } + } + + static String queryLookup( String query, String param ) { + char in[] = query.toCharArray(); + int i, ch, st, eq; + + st = eq = 0; + for( i = 0; i < in.length; i++) { + ch = in[i]; + if( ch == '&' ) { + if( eq > st ) { + String p = new String( in, st, eq - st ); + if( p.equalsIgnoreCase( param )) { + eq++; + return new String( in, eq, i - eq ); + } + } + st = i + 1; + } else if( ch == '=' ) { + eq = i; + } + } + if( eq > st ) { + String p = new String( in, st, eq - st ); + if( p.equalsIgnoreCase( param )) { + eq++; + return new String( in, eq, in.length - eq ); + } + } + + return null; + } + +UniAddress[] addresses; +int addressIndex; + + UniAddress getAddress() throws UnknownHostException { + if (addressIndex == 0) + return getFirstAddress(); + return addresses[addressIndex - 1]; + } + UniAddress getFirstAddress() throws UnknownHostException { + addressIndex = 0; + + String host = url.getHost(); + String path = url.getPath(); + String query = url.getQuery(); + + if( query != null ) { + String server = queryLookup( query, "server" ); + if( server != null && server.length() > 0 ) { + addresses = new UniAddress[1]; + addresses[0] = UniAddress.getByName( server ); + return getNextAddress(); + } + String address = queryLookup(query, "address"); + if (address != null && address.length() > 0) { + byte[] ip = java.net.InetAddress.getByName(address).getAddress(); + addresses = new UniAddress[1]; + addresses[0] = new UniAddress(java.net.InetAddress.getByAddress(host, ip)); + return getNextAddress(); + } + } + + if (host.length() == 0) { + try { + NbtAddress addr = NbtAddress.getByName( + NbtAddress.MASTER_BROWSER_NAME, 0x01, null); + addresses = new UniAddress[1]; + addresses[0] = UniAddress.getByName( addr.getHostAddress() ); + } catch( UnknownHostException uhe ) { + NtlmPasswordAuthentication.initDefaults(); + if( NtlmPasswordAuthentication.DEFAULT_DOMAIN.equals( "?" )) { + throw uhe; + } + addresses = UniAddress.getAllByName( NtlmPasswordAuthentication.DEFAULT_DOMAIN, true ); + } + } else if( path.length() == 0 || path.equals( "/" )) { + addresses = UniAddress.getAllByName( host, true ); + } else { + addresses = UniAddress.getAllByName(host, false); + } + + return getNextAddress(); + } + UniAddress getNextAddress() { + UniAddress addr = null; + if (addressIndex < addresses.length) + addr = addresses[addressIndex++]; + return addr; + } + boolean hasNextAddress() { + return addressIndex < addresses.length; + } + void connect0() throws SmbException { + try { + connect(); + } catch( UnknownHostException uhe ) { + throw new SmbException( "Failed to connect to server", uhe ); + } catch( SmbException se ) { + throw se; + } catch( IOException ioe ) { + throw new SmbException( "Failed to connect to server", ioe ); + } + } + void doConnect() throws IOException { + SmbTransport trans; + UniAddress addr; + + addr = getAddress(); + if (tree != null) { + trans = tree.session.transport; + } else { + trans = SmbTransport.getSmbTransport(addr, url.getPort()); + tree = trans.getSmbSession(auth).getSmbTree(share, null); + } + + String hostName = getServerWithDfs(); + tree.inDomainDfs = dfs.resolve(hostName, tree.share, null, auth) != null; + if (tree.inDomainDfs) { + tree.connectionState = 2; + } + + try { + if( log.level >= 3 ) + log.println( "doConnect: " + addr ); + + tree.treeConnect(null, null); + } catch (SmbAuthException sae) { + NtlmPasswordAuthentication a; + SmbSession ssn; + + if (share == null) { // IPC$ - try "anonymous" credentials + ssn = trans.getSmbSession(NtlmPasswordAuthentication.NULL); + tree = ssn.getSmbTree(null, null); + tree.treeConnect(null, null); + } else if ((a = NtlmAuthenticator.requestNtlmPasswordAuthentication( + url.toString(), sae)) != null) { + auth = a; + ssn = trans.getSmbSession(auth); + tree = ssn.getSmbTree(share, null); + tree.inDomainDfs = dfs.resolve(hostName, tree.share, null, auth) != null; + if (tree.inDomainDfs) { + tree.connectionState = 2; + } + tree.treeConnect(null, null); + } else { + if (log.level >= 1 && hasNextAddress()) + sae.printStackTrace(log); + throw sae; + } + } + } +/** + * It is not necessary to call this method directly. This is the + * URLConnection implementation of connect(). + */ + public void connect() throws IOException { + SmbTransport trans; + SmbSession ssn; + UniAddress addr; + + if( isConnected() ) { + return; + } + + getUncPath0(); + getFirstAddress(); + for ( ;; ) { + try { + doConnect(); + return; + } catch(SmbException se) { + if (getNextAddress() == null) + throw se; + if (log.level >= 3) + se.printStackTrace(log); + } + } + } + boolean isConnected() { + return tree != null && tree.connectionState == 2; + } + int open0( int flags, int access, int attrs, int options ) throws SmbException { + int f; + + connect0(); + + if( log.level >= 3 ) + log.println( "open0: " + unc ); + + /* + * NT Create AndX / Open AndX Request / Response + */ + + if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) { + SmbComNTCreateAndXResponse response = new SmbComNTCreateAndXResponse(); +SmbComNTCreateAndX request = new SmbComNTCreateAndX( unc, flags, access, shareAccess, attrs, options, null ); +if (this instanceof SmbNamedPipe) { + request.flags0 |= 0x16; + request.desiredAccess |= 0x20000; + response.isExtended = true; +} + send( request, response ); + f = response.fid; + attributes = response.extFileAttributes & ATTR_GET_MASK; + attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; + isExists = true; + } else { + SmbComOpenAndXResponse response = new SmbComOpenAndXResponse(); + send( new SmbComOpenAndX( unc, access, flags, null ), response ); + f = response.fid; + } + + return f; + } + void open( int flags, int access, int attrs, int options ) throws SmbException { + if( isOpen() ) { + return; + } + fid = open0( flags, access, attrs, options ); + opened = true; + tree_num = tree.tree_num; + } + boolean isOpen() { + boolean ans = opened && isConnected() && tree_num == tree.tree_num; + return ans; + } + void close( int f, long lastWriteTime ) throws SmbException { + + if( log.level >= 3 ) + log.println( "close: " + f ); + + /* + * Close Request / Response + */ + + send( new SmbComClose( f, lastWriteTime ), blank_resp() ); + } + void close( long lastWriteTime ) throws SmbException { + if( isOpen() == false ) { + return; + } + close( fid, lastWriteTime ); + opened = false; + } + void close() throws SmbException { + close( 0L ); + } + +/** + * Returns the NtlmPasswordAuthentication object used as + * credentials with this file or pipe. This can be used to retrieve the + * username for example: + * + * String username = f.getPrincipal().getName(); + * + * The Principal object returned will never be null + * however the username can be null indication anonymous + * credentials were used (e.g. some IPC$ services). + */ + + public Principal getPrincipal() { + return auth; + } + +/** + * Returns the last component of the target URL. This will + * effectively be the name of the file or directory represented by this + * SmbFile or in the case of URLs that only specify a server + * or workgroup, the server or workgroup will be returned. The name of + * the root URL smb:// is also smb://. If this + * SmbFile refers to a workgroup, server, share, or directory, + * the name will include a trailing slash '/' so that composing new + * SmbFiles will maintain the trailing slash requirement. + * + * @return The last component of the URL associated with this SMB + * resource or smb:// if the resource is smb:// + * itself. + */ + + public String getName() { + getUncPath0(); + if( canon.length() > 1 ) { + int i = canon.length() - 2; + while( canon.charAt( i ) != '/' ) { + i--; + } + return canon.substring( i + 1 ); + } else if( share != null ) { + return share + '/'; + } else if( url.getHost().length() > 0 ) { + return url.getHost() + '/'; + } else { + return "smb://"; + } + } + +/** + * Everything but the last component of the URL representing this SMB + * resource is effectivly it's parent. The root URL smb:// + * does not have a parent. In this case smb:// is returned. + * + * @return The parent directory of this SMB resource or + * smb:// if the resource refers to the root of the URL + * hierarchy which incedentally is also smb://. + */ + + public String getParent() { + String str = url.getAuthority(); + + if( str.length() > 0 ) { + StringBuffer sb = new StringBuffer( "smb://" ); + + sb.append( str ); + + getUncPath0(); + if( canon.length() > 1 ) { + sb.append( canon ); + } else { + sb.append( '/' ); + } + + str = sb.toString(); + + int i = str.length() - 2; + while( str.charAt( i ) != '/' ) { + i--; + } + + return str.substring( 0, i + 1 ); + } + + return "smb://"; + } + +/** + * Returns the full uncanonicalized URL of this SMB resource. An + * SmbFile constructed with the result of this method will + * result in an SmbFile that is equal to the original. + * + * @return The uncanonicalized full URL of this SMB resource. + */ + + public String getPath() { + return url.toString(); + } + + String getUncPath0() { + if( unc == null ) { + char[] in = url.getPath().toCharArray(); + char[] out = new char[in.length]; + int length = in.length, i, o, state, s; + + /* The canonicalization routine + */ + state = 0; + o = 0; + for( i = 0; i < length; i++ ) { + switch( state ) { + case 0: + if( in[i] != '/' ) { + return null; + } + out[o++] = in[i]; + state = 1; + break; + case 1: + if( in[i] == '/' ) { + break; + } else if( in[i] == '.' && + (( i + 1 ) >= length || in[i + 1] == '/' )) { + i++; + break; + } else if(( i + 1 ) < length && + in[i] == '.' && + in[i + 1] == '.' && + (( i + 2 ) >= length || in[i + 2] == '/' )) { + i += 2; + if( o == 1 ) break; + do { + o--; + } while( o > 1 && out[o - 1] != '/' ); + break; + } + state = 2; + case 2: + if( in[i] == '/' ) { + state = 1; + } + out[o++] = in[i]; + break; + } + } + + canon = new String( out, 0, o ); + + if( o > 1 ) { + o--; + i = canon.indexOf( '/', 1 ); + if( i < 0 ) { + share = canon.substring( 1 ); + unc = "\\"; + } else if( i == o ) { + share = canon.substring( 1, i ); + unc = "\\"; + } else { + share = canon.substring( 1, i ); + unc = canon.substring( i, out[o] == '/' ? o : o + 1 ); + unc = unc.replace( '/', '\\' ); + } + } else { + share = null; + unc = "\\"; + } + } + return unc; + } +/** + * Retuns the Windows UNC style path with backslashs intead of forward slashes. + * + * @return The UNC path. + */ + public String getUncPath() { + getUncPath0(); + if( share == null ) { + return "\\\\" + url.getHost(); + } + return "\\\\" + url.getHost() + canon.replace( '/', '\\' ); + } +/** + * Returns the full URL of this SMB resource with '.' and '..' components + * factored out. An SmbFile constructed with the result of + * this method will result in an SmbFile that is equal to + * the original. + * + * @return The canonicalized URL of this SMB resource. + */ + + public String getCanonicalPath() { + String str = url.getAuthority(); + getUncPath0(); + if( str.length() > 0 ) { + return "smb://" + url.getAuthority() + canon; + } + return "smb://"; + } + +/** + * Retrieves the share associated with this SMB resource. In + * the case of smb://, smb://workgroup/, + * and smb://server/ URLs which do not specify a share, + * null will be returned. + * + * @return The share component or null if there is no share + */ + + public String getShare() { + return share; + } + + String getServerWithDfs() { + if (dfsReferral != null) { + return dfsReferral.server; + } + return getServer(); + } +/** + * Retrieve the hostname of the server for this SMB resource. If this + * SmbFile references a workgroup, the name of the workgroup + * is returned. If this SmbFile refers to the root of this + * SMB network hierarchy, null is returned. + * + * @return The server or workgroup name or null if this + * SmbFile refers to the root smb:// resource. + */ + + public String getServer() { + String str = url.getHost(); + if( str.length() == 0 ) { + return null; + } + return str; + } + +/** + * Returns type of of object this SmbFile represents. + * @return TYPE_FILESYSTEM, TYPE_WORKGROUP, TYPE_SERVER, TYPE_SHARE, + * TYPE_PRINTER, TYPE_NAMED_PIPE, or TYPE_COMM. + */ + public int getType() throws SmbException { + if( type == 0 ) { + if( getUncPath0().length() > 1 ) { + type = TYPE_FILESYSTEM; + } else if( share != null ) { + // treeConnect good enough to test service type + connect0(); + if( share.equals( "IPC$" )) { + type = TYPE_NAMED_PIPE; + } else if( tree.service.equals( "LPT1:" )) { + type = TYPE_PRINTER; + } else if( tree.service.equals( "COMM" )) { + type = TYPE_COMM; + } else { + type = TYPE_SHARE; + } + } else if( url.getAuthority() == null || url.getAuthority().length() == 0 ) { + type = TYPE_WORKGROUP; + } else { + UniAddress addr; + try { + addr = getAddress(); + } catch( UnknownHostException uhe ) { + throw new SmbException( url.toString(), uhe ); + } + if( addr.getAddress() instanceof NbtAddress ) { + int code = ((NbtAddress)addr.getAddress()).getNameType(); + if( code == 0x1d || code == 0x1b ) { + type = TYPE_WORKGROUP; + return type; + } + } + type = TYPE_SERVER; + } + } + return type; + } + boolean isWorkgroup0() throws UnknownHostException { + if( type == TYPE_WORKGROUP || url.getHost().length() == 0 ) { + type = TYPE_WORKGROUP; + return true; + } else { + getUncPath0(); + if( share == null ) { + UniAddress addr = getAddress(); + if( addr.getAddress() instanceof NbtAddress ) { + int code = ((NbtAddress)addr.getAddress()).getNameType(); + if( code == 0x1d || code == 0x1b ) { + type = TYPE_WORKGROUP; + return true; + } + } + type = TYPE_SERVER; + } + } + return false; + } + + Info queryPath( String path, int infoLevel ) throws SmbException { + connect0(); + + if (log.level >= 3) + log.println( "queryPath: " + path ); + + /* normally we'd check the negotiatedCapabilities for CAP_NT_SMBS + * however I can't seem to get a good last modified time from + * SMB_COM_QUERY_INFORMATION so if NT_SMBs are requested + * by the server than in this case that's what it will get + * regardless of what jcifs.smb.client.useNTSmbs is set + * to(overrides negotiatedCapabilities). + */ + + /* We really should do the referral before this in case + * the redirected target has different capabilities. But + * the way we have been doing that is to call exists() which + * calls this method so another technique will be necessary + * to support DFS referral _to_ Win95/98/ME. + */ + + if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) { + + /* + * Trans2 Query Path Information Request / Response + */ + + Trans2QueryPathInformationResponse response = + new Trans2QueryPathInformationResponse( infoLevel ); + send( new Trans2QueryPathInformation( path, infoLevel ), response ); + + return response.info; + } else { + + /* + * Query Information Request / Response + */ + + SmbComQueryInformationResponse response = + new SmbComQueryInformationResponse( + tree.session.transport.server.serverTimeZone * 1000 * 60L ); + send( new SmbComQueryInformation( path ), response ); + return response; + } + } + +/** + * Tests to see if the SMB resource exists. If the resource refers + * only to a server, this method determines if the server exists on the + * network and is advertising SMB services. If this resource refers to + * a workgroup, this method determines if the workgroup name is valid on + * the local SMB network. If this SmbFile refers to the root + * smb:// resource true is always returned. If + * this SmbFile is a traditional file or directory, it will + * be queried for on the specified server as expected. + * + * @return true if the resource exists or is alive or + * false otherwise + */ + + public boolean exists() throws SmbException { + + if( attrExpiration > System.currentTimeMillis() ) { + return isExists; + } + + attributes = ATTR_READONLY | ATTR_DIRECTORY; + createTime = 0L; + lastModified = 0L; + isExists = false; + + try { + if( url.getHost().length() == 0 ) { + } else if( share == null ) { + if( getType() == TYPE_WORKGROUP ) { + UniAddress.getByName( url.getHost(), true ); + } else { + UniAddress.getByName( url.getHost() ).getHostName(); + } + } else if( getUncPath0().length() == 1 || + share.equalsIgnoreCase( "IPC$" )) { + connect0(); // treeConnect is good enough + } else { + Info info = queryPath( getUncPath0(), + Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); + attributes = info.getAttributes(); + createTime = info.getCreateTime(); + lastModified = info.getLastWriteTime(); + } + + /* If any of the above fail, isExists will not be set true + */ + + isExists = true; + + } catch( UnknownHostException uhe ) { + } catch( SmbException se ) { + switch (se.getNtStatus()) { + case NtStatus.NT_STATUS_NO_SUCH_FILE: + case NtStatus.NT_STATUS_OBJECT_NAME_INVALID: + case NtStatus.NT_STATUS_OBJECT_NAME_NOT_FOUND: + case NtStatus.NT_STATUS_OBJECT_PATH_NOT_FOUND: + break; + default: + throw se; + } + } + + attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; + + return isExists; + } + +/** + * Tests to see if the file this SmbFile represents can be + * read. Because any file, directory, or other resource can be read if it + * exists, this method simply calls the exists method. + * + * @return true if the file is read-only + */ + + public boolean canRead() throws SmbException { + if( getType() == TYPE_NAMED_PIPE ) { // try opening the pipe for reading? + return true; + } + return exists(); // try opening and catch sharing violation? + } + +/** + * Tests to see if the file this SmbFile represents + * exists and is not marked read-only. By default, resources are + * considered to be read-only and therefore for smb://, + * smb://workgroup/, and smb://server/ resources + * will be read-only. + * + * @return true if the resource exists is not marked + * read-only + */ + + public boolean canWrite() throws SmbException { + if( getType() == TYPE_NAMED_PIPE ) { // try opening the pipe for writing? + return true; + } + return exists() && ( attributes & ATTR_READONLY ) == 0; + } + +/** + * Tests to see if the file this SmbFile represents is a directory. + * + * @return true if this SmbFile is a directory + */ + + public boolean isDirectory() throws SmbException { + if( getUncPath0().length() == 1 ) { + return true; + } + if (!exists()) return false; + return ( attributes & ATTR_DIRECTORY ) == ATTR_DIRECTORY; + } + +/** + * Tests to see if the file this SmbFile represents is not a directory. + * + * @return true if this SmbFile is not a directory + */ + + public boolean isFile() throws SmbException { + if( getUncPath0().length() == 1 ) { + return false; + } + exists(); + return ( attributes & ATTR_DIRECTORY ) == 0; + } + +/** + * Tests to see if the file this SmbFile represents is marked as + * hidden. This method will also return true for shares with names that + * end with '$' such as IPC$ or C$. + * + * @return true if the SmbFile is marked as being hidden + */ + + public boolean isHidden() throws SmbException { + if( share == null ) { + return false; + } else if( getUncPath0().length() == 1 ) { + if( share.endsWith( "$" )) { + return true; + } + return false; + } + exists(); + return ( attributes & ATTR_HIDDEN ) == ATTR_HIDDEN; + } + +/** + * If the path of this SmbFile falls within a DFS volume, + * this method will return the referral path to which it maps. Otherwise + * null is returned. + */ + + public String getDfsPath() throws SmbException { + resolveDfs(null); + if( dfsReferral == null ) { + return null; + } + String path = "smb:/" + dfsReferral.server + "/" + dfsReferral.share + unc; + path = path.replace( '\\', '/' ); + if (isDirectory()) { + path += '/'; + } + return path; + } + +/** + * Retrieve the time this SmbFile was created. The value + * returned is suitable for constructing a {@link java.util.Date} object + * (i.e. seconds since Epoch 1970). Times should be the same as those + * reported using the properties dialog of the Windows Explorer program. + * + * For Win95/98/Me this is actually the last write time. It is currently + * not possible to retrieve the create time from files on these systems. + * + * @return The number of milliseconds since the 00:00:00 GMT, January 1, + * 1970 as a long value + */ + public long createTime() throws SmbException { + if( getUncPath0().length() > 1 ) { + exists(); + return createTime; + } + return 0L; + } +/** + * Retrieve the last time the file represented by this + * SmbFile was modified. The value returned is suitable for + * constructing a {@link java.util.Date} object (i.e. seconds since Epoch + * 1970). Times should be the same as those reported using the properties + * dialog of the Windows Explorer program. + * + * @return The number of milliseconds since the 00:00:00 GMT, January 1, + * 1970 as a long value + */ + public long lastModified() throws SmbException { + if( getUncPath0().length() > 1 ) { + exists(); + return lastModified; + } + return 0L; + } +/** + * List the contents of this SMB resource. The list returned by this + * method will be; + * + *

    + *
  • files and directories contained within this resource if the + * resource is a normal disk file directory, + *
  • all available NetBIOS workgroups or domains if this resource is + * the top level URL smb://, + *
  • all servers registered as members of a NetBIOS workgroup if this + * resource refers to a workgroup in a smb://workgroup/ URL, + *
  • all browseable shares of a server including printers, IPC + * services, or disk volumes if this resource is a server URL in the form + * smb://server/, + *
  • or null if the resource cannot be resolved. + *
+ * + * @return A String[] array of files and directories, + * workgroups, servers, or shares depending on the context of the + * resource URL + */ + public String[] list() throws SmbException { + return list( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); + } + +/** + * List the contents of this SMB resource. The list returned will be + * identical to the list returned by the parameterless list() + * method minus filenames filtered by the specified filter. + * + * @param filter a filename filter to exclude filenames from the results + * @throws SmbException + # @return An array of filenames + */ + public String[] list( SmbFilenameFilter filter ) throws SmbException { + return list( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, filter, null ); + } + +/** + * List the contents of this SMB resource as an array of + * SmbFile objects. This method is much more efficient than + * the regular list method when querying attributes of each + * file in the result set. + *

+ * The list of SmbFiles returned by this method will be; + * + *

    + *
  • files and directories contained within this resource if the + * resource is a normal disk file directory, + *
  • all available NetBIOS workgroups or domains if this resource is + * the top level URL smb://, + *
  • all servers registered as members of a NetBIOS workgroup if this + * resource refers to a workgroup in a smb://workgroup/ URL, + *
  • all browseable shares of a server including printers, IPC + * services, or disk volumes if this resource is a server URL in the form + * smb://server/, + *
  • or null if the resource cannot be resolved. + *
+ * + * @return An array of SmbFile objects representing file + * and directories, workgroups, servers, or shares depending on the context + * of the resource URL + */ + public SmbFile[] listFiles() throws SmbException { + return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); + } + +/** + * The CIFS protocol provides for DOS "wildcards" to be used as + * a performance enhancement. The client does not have to filter + * the names and the server does not have to return all directory + * entries. + *

+ * The wildcard expression may consist of two special meta + * characters in addition to the normal filename characters. The '*' + * character matches any number of characters in part of a name. If + * the expression begins with one or more '?'s then exactly that + * many characters will be matched whereas if it ends with '?'s + * it will match that many characters or less. + *

+ * Wildcard expressions will not filter workgroup names or server names. + * + *

+ * winnt> ls c?o*
+ * clock.avi                  -rw--      82944 Mon Oct 14 1996 1:38 AM
+ * Cookies                    drw--          0 Fri Nov 13 1998 9:42 PM
+ * 2 items in 5ms
+ * 
+ * + * @param wildcard a wildcard expression + * @throws SmbException + * @return An array of SmbFile objects representing file + * and directories, workgroups, servers, or shares depending on the context + * of the resource URL + */ + + public SmbFile[] listFiles( String wildcard ) throws SmbException { + return listFiles( wildcard, ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); + } +/** + * List the contents of this SMB resource. The list returned will be + * identical to the list returned by the parameterless listFiles() + * method minus files filtered by the specified filename filter. + * + * @param filter a filter to exclude files from the results + * @return An array of SmbFile objects + * @throws SmbException + */ + public SmbFile[] listFiles( SmbFilenameFilter filter ) throws SmbException { + return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, filter, null ); + } +/** + * List the contents of this SMB resource. The list returned will be + * identical to the list returned by the parameterless listFiles() + * method minus filenames filtered by the specified filter. + * + * @param filter a file filter to exclude files from the results + * @return An array of SmbFile objects + */ + public SmbFile[] listFiles( SmbFileFilter filter ) throws SmbException { + return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, filter ); + } + String[] list( String wildcard, int searchAttributes, + SmbFilenameFilter fnf, SmbFileFilter ff ) throws SmbException { + ArrayList list = new ArrayList(); + doEnum(list, false, wildcard, searchAttributes, fnf, ff); + return (String[])list.toArray(new String[list.size()]); + } + SmbFile[] listFiles( String wildcard, int searchAttributes, + SmbFilenameFilter fnf, SmbFileFilter ff ) throws SmbException { + ArrayList list = new ArrayList(); + doEnum(list, true, wildcard, searchAttributes, fnf, ff); + return (SmbFile[])list.toArray(new SmbFile[list.size()]); + } + void doEnum(ArrayList list, + boolean files, + String wildcard, + int searchAttributes, + SmbFilenameFilter fnf, + SmbFileFilter ff) throws SmbException { + if (ff != null && ff instanceof DosFileFilter) { + DosFileFilter dff = (DosFileFilter)ff; + if (dff.wildcard != null) + wildcard = dff.wildcard; + searchAttributes = dff.attributes; + } + + try { + int hostlen = url.getHost().length(); + if (hostlen == 0 || getType() == TYPE_WORKGROUP) { + doNetServerEnum(list, files, wildcard, searchAttributes, fnf, ff); + } else if (share == null) { + doShareEnum(list, files, wildcard, searchAttributes, fnf, ff); + } else { + doFindFirstNext(list, files, wildcard, searchAttributes, fnf, ff); + } + } catch (UnknownHostException uhe) { + throw new SmbException(url.toString(), uhe); + } catch (MalformedURLException mue) { + throw new SmbException(url.toString(), mue); + } + } + void doShareEnum(ArrayList list, + boolean files, + String wildcard, + int searchAttributes, + SmbFilenameFilter fnf, + SmbFileFilter ff) throws SmbException, + UnknownHostException, + MalformedURLException { + String p = url.getPath(); + IOException last = null; + FileEntry[] entries; + UniAddress addr; + FileEntry e; + HashMap map; + + if (p.lastIndexOf('/') != (p.length() - 1)) + throw new SmbException(url.toString() + " directory must end with '/'"); + if (getType() != TYPE_SERVER) + throw new SmbException("The requested list operations is invalid: " + url.toString()); + + map = new HashMap(); + + if (dfs.isTrustedDomain(getServer(), auth)) { + /* The server name is actually the name of a trusted + * domain. Add DFS roots to the list. + */ + try { + entries = doDfsRootEnum(); + for (int ei = 0; ei < entries.length; ei++) { + e = entries[ei]; + if (map.containsKey(e) == false) + map.put(e, e); + } + } catch (IOException ioe) { + if (log.level >= 4) + ioe.printStackTrace(log); + } + } + + addr = getFirstAddress(); + while (addr != null) { + try { + doConnect(); + try { + entries = doMsrpcShareEnum(); + } catch(IOException ioe) { + if (log.level >= 3) + ioe.printStackTrace(log); + entries = doNetShareEnum(); + } + for (int ei = 0; ei < entries.length; ei++) { + e = entries[ei]; + if (map.containsKey(e) == false) + map.put(e, e); + } + break; + } catch(IOException ioe) { + if (log.level >= 3) + ioe.printStackTrace(log); + last = ioe; + } + addr = getNextAddress(); + } + + if (last != null && map.isEmpty()) { + if (last instanceof SmbException == false) + throw new SmbException(url.toString(), last); + throw (SmbException)last; + } + + Iterator iter = map.keySet().iterator(); + while (iter.hasNext()) { + e = (FileEntry)iter.next(); + String name = e.getName(); + if (fnf != null && fnf.accept(this, name) == false) + continue; + if (name.length() > 0) { + // if !files we don't need to create SmbFiles here + SmbFile f = new SmbFile(this, name, e.getType(), + ATTR_READONLY | ATTR_DIRECTORY, 0L, 0L, 0L ); + if (ff != null && ff.accept(f) == false) + continue; + if (files) { + list.add(f); + } else { + list.add(name); + } + } + } + } + FileEntry[] doDfsRootEnum() throws IOException { + MsrpcDfsRootEnum rpc; + DcerpcHandle handle = null; + FileEntry[] entries; + + handle = DcerpcHandle.getHandle("ncacn_np:" + + getAddress().getHostAddress() + + "[\\PIPE\\netdfs]", auth); + try { + rpc = new MsrpcDfsRootEnum(getServer()); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, true); + return rpc.getEntries(); + } finally { + try { + handle.close(); + } catch(IOException ioe) { + if (log.level >= 4) + ioe.printStackTrace(log); + } + } + } + FileEntry[] doMsrpcShareEnum() throws IOException { + MsrpcShareEnum rpc; + DcerpcHandle handle; + + rpc = new MsrpcShareEnum(url.getHost()); + + /* JCIFS will build a composite list of shares if the target host has + * multiple IP addresses such as when domain-based DFS is in play. Because + * of this, to ensure that we query each IP individually without re-resolving + * the hostname and getting a different IP, we must use the current addresses + * IP rather than just url.getHost() like we were using prior to 1.2.16. + */ + + handle = DcerpcHandle.getHandle("ncacn_np:" + + getAddress().getHostAddress() + + "[\\PIPE\\srvsvc]", auth); + + try { + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, true); + return rpc.getEntries(); + } finally { + try { + handle.close(); + } catch(IOException ioe) { + if (log.level >= 4) + ioe.printStackTrace(log); + } + } + } + FileEntry[] doNetShareEnum() throws SmbException { + SmbComTransaction req = new NetShareEnum(); + SmbComTransactionResponse resp = new NetShareEnumResponse(); + + send(req, resp); + + if (resp.status != SmbException.ERROR_SUCCESS) + throw new SmbException(resp.status, true); + + return resp.results; + } + void doNetServerEnum(ArrayList list, + boolean files, + String wildcard, + int searchAttributes, + SmbFilenameFilter fnf, + SmbFileFilter ff) throws SmbException, + UnknownHostException, + MalformedURLException { + int listType = url.getHost().length() == 0 ? 0 : getType(); + SmbComTransaction req; + SmbComTransactionResponse resp; + + if (listType == 0) { + connect0(); + req = new NetServerEnum2(tree.session.transport.server.oemDomainName, + NetServerEnum2.SV_TYPE_DOMAIN_ENUM ); + resp = new NetServerEnum2Response(); + } else if (listType == TYPE_WORKGROUP) { + req = new NetServerEnum2(url.getHost(), NetServerEnum2.SV_TYPE_ALL); + resp = new NetServerEnum2Response(); + } else { + throw new SmbException( "The requested list operations is invalid: " + url.toString() ); + } + + boolean more; + do { + int n; + + send(req, resp); + + if (resp.status != SmbException.ERROR_SUCCESS && + resp.status != SmbException.ERROR_MORE_DATA) { + throw new SmbException( resp.status, true ); + } + more = resp.status == SmbException.ERROR_MORE_DATA; + + n = more ? resp.numEntries - 1 : resp.numEntries; + for (int i = 0; i < n; i++) { + FileEntry e = resp.results[i]; + String name = e.getName(); + if (fnf != null && fnf.accept(this, name) == false) + continue; + if (name.length() > 0) { + // if !files we don't need to create SmbFiles here + SmbFile f = new SmbFile(this, name, e.getType(), + ATTR_READONLY | ATTR_DIRECTORY, 0L, 0L, 0L ); + if (ff != null && ff.accept(f) == false) + continue; + if (files) { + list.add(f); + } else { + list.add(name); + } + } + } + if (getType() != TYPE_WORKGROUP) { + break; + } + req.subCommand = (byte)SmbComTransaction.NET_SERVER_ENUM3; + req.reset(0, ((NetServerEnum2Response)resp).lastName); + resp.reset(); + } while(more); + } + void doFindFirstNext( ArrayList list, + boolean files, + String wildcard, + int searchAttributes, + SmbFilenameFilter fnf, + SmbFileFilter ff ) throws SmbException, UnknownHostException, MalformedURLException { + SmbComTransaction req; + Trans2FindFirst2Response resp; + int sid; + String path = getUncPath0(); + String p = url.getPath(); + + if( p.lastIndexOf( '/' ) != ( p.length() - 1 )) { + throw new SmbException( url.toString() + " directory must end with '/'" ); + } + + req = new Trans2FindFirst2( path, wildcard, searchAttributes ); + resp = new Trans2FindFirst2Response(); + + if( log.level >= 3 ) + log.println( "doFindFirstNext: " + req.path ); + + send( req, resp ); + + sid = resp.sid; + req = new Trans2FindNext2( sid, resp.resumeKey, resp.lastName ); + + /* The only difference between first2 and next2 responses is subCommand + * so let's recycle the response object. + */ + resp.subCommand = SmbComTransaction.TRANS2_FIND_NEXT2; + + for( ;; ) { + for( int i = 0; i < resp.numEntries; i++ ) { + FileEntry e = resp.results[i]; + String name = e.getName(); + if( name.length() < 3 ) { + int h = name.hashCode(); + if( h == HASH_DOT || h == HASH_DOT_DOT ) { + if (name.equals(".") || name.equals("..")) + continue; + } + } + if( fnf != null && fnf.accept( this, name ) == false ) { + continue; + } + if( name.length() > 0 ) { + SmbFile f = new SmbFile( this, name, TYPE_FILESYSTEM, + e.getAttributes(), e.createTime(), e.lastModified(), e.length() ); + if( ff != null && ff.accept( f ) == false ) { + continue; + } + if( files ) { + list.add( f ); + } else { + list.add( name ); + } + } + } + + if( resp.isEndOfSearch || resp.numEntries == 0 ) { + break; + } + + req.reset( resp.resumeKey, resp.lastName ); + resp.reset(); + send( req, resp ); + } + + try { + send( new SmbComFindClose2( sid ), blank_resp() ); + } catch (SmbException se) { + if( log.level >= 4 ) + se.printStackTrace( log ); + } + } + +/** + * Changes the name of the file this SmbFile represents to the name + * designated by the SmbFile argument. + *

+ * Remember: SmbFiles are immutible and therefore + * the path associated with this SmbFile object will not + * change). To access the renamed file it is necessary to construct a + * new SmbFile. + * + * @param dest An SmbFile that represents the new pathname + * @throws NullPointerException + * If the dest argument is null + */ + public void renameTo( SmbFile dest ) throws SmbException { + if( getUncPath0().length() == 1 || dest.getUncPath0().length() == 1 ) { + throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); + } + + resolveDfs(null); + dest.resolveDfs(null); + + if (!tree.equals(dest.tree)) { + throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); + } + + if( log.level >= 3 ) + log.println( "renameTo: " + unc + " -> " + dest.unc ); + + attrExpiration = sizeExpiration = 0; + dest.attrExpiration = 0; + + /* + * Rename Request / Response + */ + + send( new SmbComRename( unc, dest.unc ), blank_resp() ); + } + + class WriterThread extends Thread { + byte[] b; + int n; + long off; + boolean ready; + SmbFile dest; + SmbException e = null; + boolean useNTSmbs; + SmbComWriteAndX reqx; + SmbComWrite req; + ServerMessageBlock resp; + + WriterThread() throws SmbException { + super( "JCIFS-WriterThread" ); + useNTSmbs = tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS ); + if( useNTSmbs ) { + reqx = new SmbComWriteAndX(); + resp = new SmbComWriteAndXResponse(); + } else { + req = new SmbComWrite(); + resp = new SmbComWriteResponse(); + } + ready = false; + } + + synchronized void write( byte[] b, int n, SmbFile dest, long off ) { + this.b = b; + this.n = n; + this.dest = dest; + this.off = off; + ready = false; + notify(); + } + + public void run() { + synchronized( this ) { + try { + for( ;; ) { + notify(); + ready = true; + while( ready ) { + wait(); + } + if( n == -1 ) { + return; + } + if( useNTSmbs ) { + reqx.setParam( dest.fid, off, n, b, 0, n ); + dest.send( reqx, resp ); + } else { + req.setParam( dest.fid, off, n, b, 0, n ); + dest.send( req, resp ); + } + } + } catch( SmbException e ) { + this.e = e; + } catch( Exception x ) { + this.e = new SmbException( "WriterThread", x ); + } + notify(); + } + } + } + void copyTo0( SmbFile dest, byte[][] b, int bsize, WriterThread w, + SmbComReadAndX req, SmbComReadAndXResponse resp ) throws SmbException { + int i; + + if( attrExpiration < System.currentTimeMillis() ) { + attributes = ATTR_READONLY | ATTR_DIRECTORY; + createTime = 0L; + lastModified = 0L; + isExists = false; + + Info info = queryPath( getUncPath0(), + Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); + attributes = info.getAttributes(); + createTime = info.getCreateTime(); + lastModified = info.getLastWriteTime(); + + /* If any of the above fails, isExists will not be set true + */ + + isExists = true; + attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; + } + + if( isDirectory() ) { + SmbFile[] files; + SmbFile ndest; + + String path = dest.getUncPath0(); + if( path.length() > 1 ) { + try { + dest.mkdir(); + dest.setPathInformation( attributes, createTime, lastModified ); + } catch( SmbException se ) { + if( se.getNtStatus() != NtStatus.NT_STATUS_ACCESS_DENIED && + se.getNtStatus() != NtStatus.NT_STATUS_OBJECT_NAME_COLLISION ) { + throw se; + } + } + } + + files = listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); + try { + for( i = 0; i < files.length; i++ ) { + ndest = new SmbFile( dest, + files[i].getName(), + files[i].type, + files[i].attributes, + files[i].createTime, + files[i].lastModified, + files[i].size ); + files[i].copyTo0( ndest, b, bsize, w, req, resp ); + } + } catch( UnknownHostException uhe ) { + throw new SmbException( url.toString(), uhe ); + } catch( MalformedURLException mue ) { + throw new SmbException( url.toString(), mue ); + } + } else { + long off; + + try { + open( SmbFile.O_RDONLY, 0, ATTR_NORMAL, 0 ); + try { + dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC, + FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES, + attributes, 0 ); + } catch( SmbAuthException sae ) { + if(( dest.attributes & ATTR_READONLY ) != 0 ) { + /* Remove READONLY and try again + */ + dest.setPathInformation( dest.attributes & ~ATTR_READONLY, 0L, 0L ); + dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC, + FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES, + attributes, 0 ); + } else { + throw sae; + } + } + + i = 0; + off = 0L; + for( ;; ) { + req.setParam( fid, off, bsize ); + resp.setParam( b[i], 0 ); + send( req, resp ); + + synchronized( w ) { + if( w.e != null ) { + throw w.e; + } + while( !w.ready ) { + try { + w.wait(); + } catch( InterruptedException ie ) { + throw new SmbException( dest.url.toString(), ie ); + } + } + if( w.e != null ) { + throw w.e; + } + if( resp.dataLength <= 0 ) { + break; + } + w.write( b[i], resp.dataLength, dest, off ); + } + + i = i == 1 ? 0 : 1; + off += resp.dataLength; + } + + dest.send( new Trans2SetFileInformation( + dest.fid, attributes, createTime, lastModified ), + new Trans2SetFileInformationResponse() ); + dest.close( 0L ); + } catch( Exception ex ) { + if( log.level > 1 ) + ex.printStackTrace( log ); + } finally { + close(); + } + } + } +/** + * This method will copy the file or directory represented by this + * SmbFile and it's sub-contents to the location specified by the + * dest parameter. This file and the destination file do not + * need to be on the same host. This operation does not copy extended + * file attibutes such as ACLs but it does copy regular attributes as + * well as create and last write times. This method is almost twice as + * efficient as manually copying as it employs an additional write + * thread to read and write data concurrently. + *

+ * It is not possible (nor meaningful) to copy entire workgroups or + * servers. + * + * @param dest the destination file or directory + * @throws SmbException + */ + public void copyTo( SmbFile dest ) throws SmbException { + SmbComReadAndX req; + SmbComReadAndXResponse resp; + WriterThread w; + int bsize; + byte[][] b; + + /* Should be able to copy an entire share actually + */ + if( share == null || dest.share == null) { + throw new SmbException( "Invalid operation for workgroups or servers" ); + } + + req = new SmbComReadAndX(); + resp = new SmbComReadAndXResponse(); + + connect0(); + dest.connect0(); + + /* At this point the maxBufferSize values are from the server + * exporting the volumes, not the one that we will actually + * end up performing IO with. If the server hosting the + * actual files has a smaller maxBufSize this could be + * incorrect. To handle this properly it is necessary + * to redirect the tree to the target server first before + * establishing buffer size. These exists() calls facilitate + * that. + */ + resolveDfs(null); + + /* It is invalid for the source path to be a child of the destination + * path or visa versa. + */ + try { + if (getAddress().equals( dest.getAddress() ) && + canon.regionMatches( true, 0, dest.canon, 0, + Math.min( canon.length(), dest.canon.length() ))) { + throw new SmbException( "Source and destination paths overlap." ); + } + } catch (UnknownHostException uhe) { + } + + w = new WriterThread(); + w.setDaemon( true ); + w.start(); + + /* Downgrade one transport to the lower of the negotiated buffer sizes + * so we can just send whatever is received. + */ + + SmbTransport t1 = tree.session.transport; + SmbTransport t2 = dest.tree.session.transport; + + if( t1.snd_buf_size < t2.snd_buf_size ) { + t2.snd_buf_size = t1.snd_buf_size; + } else { + t1.snd_buf_size = t2.snd_buf_size; + } + + bsize = Math.min( t1.rcv_buf_size - 70, t1.snd_buf_size - 70 ); + b = new byte[2][bsize]; + + try { + copyTo0( dest, b, bsize, w, req, resp ); + } finally { + w.write( null, -1, null, 0 ); + } + } + +/** + * This method will delete the file or directory specified by this + * SmbFile. If the target is a directory, the contents of + * the directory will be deleted as well. If a file within the directory or + * it's sub-directories is marked read-only, the read-only status will + * be removed and the file will be deleted. + * + * @throws SmbException + */ + public void delete() throws SmbException { + exists(); + getUncPath0(); + delete( unc ); + } + void delete( String fileName ) throws SmbException { + if( getUncPath0().length() == 1 ) { + throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); + } + + if( System.currentTimeMillis() > attrExpiration ) { + attributes = ATTR_READONLY | ATTR_DIRECTORY; + createTime = 0L; + lastModified = 0L; + isExists = false; + + Info info = queryPath( getUncPath0(), + Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); + attributes = info.getAttributes(); + createTime = info.getCreateTime(); + lastModified = info.getLastWriteTime(); + + attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; + isExists = true; + } + + if(( attributes & ATTR_READONLY ) != 0 ) { + setReadWrite(); + } + + /* + * Delete or Delete Directory Request / Response + */ + + if( log.level >= 3 ) + log.println( "delete: " + fileName ); + + if(( attributes & ATTR_DIRECTORY ) != 0 ) { + + /* Recursively delete directory contents + */ + + try { + SmbFile[] l = listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); + for( int i = 0; i < l.length; i++ ) { + l[i].delete(); + } + } catch( SmbException se ) { + /* Oracle FilesOnline version 9.0.4 doesn't send '.' and '..' so + * listFiles may generate undesireable "cannot find + * the file specified". + */ + if( se.getNtStatus() != SmbException.NT_STATUS_NO_SUCH_FILE ) { + throw se; + } + } + + send( new SmbComDeleteDirectory( fileName ), blank_resp() ); + } else { + send( new SmbComDelete( fileName ), blank_resp() ); + } + + attrExpiration = sizeExpiration = 0; + } + +/** + * Returns the length of this SmbFile in bytes. If this object + * is a TYPE_SHARE the total capacity of the disk shared in + * bytes is returned. If this object is a directory or a type other than + * TYPE_SHARE, 0L is returned. + * + * @return The length of the file in bytes or 0 if this + * SmbFile is not a file. + * @throws SmbException + */ + + public long length() throws SmbException { + if( sizeExpiration > System.currentTimeMillis() ) { + return size; + } + + if( getType() == TYPE_SHARE ) { + Trans2QueryFSInformationResponse response; + int level = Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION; + + response = new Trans2QueryFSInformationResponse( level ); + send( new Trans2QueryFSInformation( level ), response ); + + size = response.info.getCapacity(); + } else if( getUncPath0().length() > 1 && type != TYPE_NAMED_PIPE ) { + Info info = queryPath( getUncPath0(), + Trans2QueryPathInformationResponse.SMB_QUERY_FILE_STANDARD_INFO ); + size = info.getSize(); + } else { + size = 0L; + } + sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod; + return size; + } + +/** + * This method returns the free disk space in bytes of the drive this share + * represents or the drive on which the directory or file resides. Objects + * other than TYPE_SHARE or TYPE_FILESYSTEM will result + * in 0L being returned. + * + * @return the free disk space in bytes of the drive on which this file or + * directory resides + */ + public long getDiskFreeSpace() throws SmbException { + if( getType() == TYPE_SHARE || type == TYPE_FILESYSTEM ) { + int level = Trans2QueryFSInformationResponse.SMB_FS_FULL_SIZE_INFORMATION; + try { + return queryFSInformation(level); + } catch( SmbException ex ) { + switch (ex.getNtStatus()) { + case NtStatus.NT_STATUS_INVALID_INFO_CLASS: + case NtStatus.NT_STATUS_UNSUCCESSFUL: // NetApp Filer + // SMB_FS_FULL_SIZE_INFORMATION not supported by the server. + level = Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION; + return queryFSInformation(level); + } + throw ex; + } + } + return 0L; + } + + private long queryFSInformation( int level ) throws SmbException { + Trans2QueryFSInformationResponse response; + + response = new Trans2QueryFSInformationResponse( level ); + send( new Trans2QueryFSInformation( level ), response ); + + if( type == TYPE_SHARE ) { + size = response.info.getCapacity(); + sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod; + } + + return response.info.getFree(); + } + +/** + * Creates a directory with the path specified by this + * SmbFile. For this method to be successful, the target + * must not already exist. This method will fail when + * used with smb://, smb://workgroup/, + * smb://server/, or smb://server/share/ URLs + * because workgroups, servers, and shares cannot be dynamically created + * (although in the future it may be possible to create shares). + * + * @throws SmbException + */ + public void mkdir() throws SmbException { + String path = getUncPath0(); + + if( path.length() == 1 ) { + throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); + } + + /* + * Create Directory Request / Response + */ + + if( log.level >= 3 ) + log.println( "mkdir: " + path ); + + send( new SmbComCreateDirectory( path ), blank_resp() ); + + attrExpiration = sizeExpiration = 0; + } + +/** + * Creates a directory with the path specified by this SmbFile + * and any parent directories that do not exist. This method will fail + * when used with smb://, smb://workgroup/, + * smb://server/, or smb://server/share/ URLs + * because workgroups, servers, and shares cannot be dynamically created + * (although in the future it may be possible to create shares). + * + * @throws SmbException + */ + public void mkdirs() throws SmbException { + SmbFile parent; + + try { + parent = new SmbFile( getParent(), auth ); + } catch( IOException ioe ) { + return; + } + if( parent.exists() == false ) { + parent.mkdirs(); + } + mkdir(); + } + +/** + * Create a new file but fail if it already exists. The check for + * existance of the file and it's creation are an atomic operation with + * respect to other filesystem activities. + */ + public void createNewFile() throws SmbException { + if( getUncPath0().length() == 1 ) { + throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); + } + close( open0( O_RDWR | O_CREAT | O_EXCL, 0, ATTR_NORMAL, 0 ), 0L ); + } + + void setPathInformation( int attrs, long ctime, long mtime ) throws SmbException { + int f, dir; + + exists(); + dir = attributes & ATTR_DIRECTORY; + + f = open0( O_RDONLY, FILE_WRITE_ATTRIBUTES, + dir, dir != 0 ? 0x0001 : 0x0040 ); + send( new Trans2SetFileInformation( f, attrs | dir, ctime, mtime ), + new Trans2SetFileInformationResponse() ); + close( f, 0L ); + + attrExpiration = 0; + } + +/** + * Set the create time of the file. The time is specified as milliseconds + * from Jan 1, 1970 which is the same as that which is returned by the + * createTime() method. + *

+ * This method does not apply to workgroups, servers, or shares. + * + * @param time the create time as milliseconds since Jan 1, 1970 + */ + public void setCreateTime( long time ) throws SmbException { + if( getUncPath0().length() == 1 ) { + throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); + } + + setPathInformation( 0, time, 0L ); + } +/** + * Set the last modified time of the file. The time is specified as milliseconds + * from Jan 1, 1970 which is the same as that which is returned by the + * lastModified(), getLastModified(), and getDate() methods. + *

+ * This method does not apply to workgroups, servers, or shares. + * + * @param time the last modified time as milliseconds since Jan 1, 1970 + */ + public void setLastModified( long time ) throws SmbException { + if( getUncPath0().length() == 1 ) { + throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); + } + + setPathInformation( 0, 0L, time ); + } + +/** + * Return the attributes of this file. Attributes are represented as a + * bitset that must be masked with ATTR_* constants to determine + * if they are set or unset. The value returned is suitable for use with + * the setAttributes() method. + * + * @return the ATTR_* attributes associated with this file + * @throws SmbException + */ + public int getAttributes() throws SmbException { + if( getUncPath0().length() == 1 ) { + return 0; + } + exists(); + return attributes & ATTR_GET_MASK; + } + +/** + * Set the attributes of this file. Attributes are composed into a + * bitset by bitwise ORing the ATTR_* constants. Setting the + * value returned by getAttributes will result in both files + * having the same attributes. + * @throws SmbException + */ + public void setAttributes( int attrs ) throws SmbException { + if( getUncPath0().length() == 1 ) { + throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); + } + setPathInformation( attrs & ATTR_SET_MASK, 0L, 0L ); + } + +/** + * Make this file read-only. This is shorthand for setAttributes( + * getAttributes() | ATTR_READ_ONLY ). + * + * @throws SmbException + */ + public void setReadOnly() throws SmbException { + setAttributes( getAttributes() | ATTR_READONLY ); + } + +/** + * Turn off the read-only attribute of this file. This is shorthand for + * setAttributes( getAttributes() & ~ATTR_READONLY ). + * + * @throws SmbException + */ + public void setReadWrite() throws SmbException { + setAttributes( getAttributes() & ~ATTR_READONLY ); + } + +/** + * Returns a {@link java.net.URL} for this SmbFile. The + * URL may be used as any other URL might to + * access an SMB resource. Currently only retrieving data and information + * is supported (i.e. no doOutput). + * + * @deprecated Use getURL() instead + * @return A new {@link java.net.URL} for this SmbFile + * @throws MalformedURLException + */ + public URL toURL() throws MalformedURLException { + return url; + } + +/** + * Computes a hashCode for this file based on the URL string and IP + * address if the server. The hashing function uses the hashcode of the + * server address, the canonical representation of the URL, and does not + * compare authentication information. In essance, two + * SmbFile objects that refer to + * the same file should generate the same hashcode provided it is possible + * to make such a determination. + * + * @return A hashcode for this abstract file + * @throws SmbException + */ + + public int hashCode() { + int hash; + try { + hash = getAddress().hashCode(); + } catch( UnknownHostException uhe ) { + hash = getServer().toUpperCase().hashCode(); + } + getUncPath0(); + return hash + canon.toUpperCase().hashCode(); + } + + protected boolean pathNamesPossiblyEqual(String path1, String path2) { + int p1, p2, l1, l2; + + // if unsure return this method returns true + + p1 = path1.lastIndexOf('/'); + p2 = path2.lastIndexOf('/'); + l1 = path1.length() - p1; + l2 = path2.length() - p2; + + // anything with dots voids comparison + if (l1 > 1 && path1.charAt(p1 + 1) == '.') + return true; + if (l2 > 1 && path2.charAt(p2 + 1) == '.') + return true; + + return l1 == l2 && path1.regionMatches(true, p1, path2, p2, l1); + } +/** + * Tests to see if two SmbFile objects are equal. Two + * SmbFile objects are equal when they reference the same SMB + * resource. More specifically, two SmbFile objects are + * equals if their server IP addresses are equal and the canonicalized + * representation of their URLs, minus authentication parameters, are + * case insensitivly and lexographically equal. + *

+ * For example, assuming the server angus resolves to the + * 192.168.1.15 IP address, the below URLs would result in + * SmbFiles that are equal. + * + *

+ * smb://192.168.1.15/share/DIR/foo.txt
+ * smb://angus/share/data/../dir/foo.txt
+ * 
+ * + * @param obj Another SmbFile object to compare for equality + * @return true if the two objects refer to the same SMB resource + * and false otherwise + * @throws SmbException + */ + + public boolean equals( Object obj ) { + if (obj instanceof SmbFile) { + SmbFile f = (SmbFile)obj; + boolean ret; + + if (this == f) + return true; + + /* If uncertain, pathNamesPossiblyEqual returns true. + * Comparing canonical paths is definitive. + */ + if (pathNamesPossiblyEqual(url.getPath(), f.url.getPath())) { + + getUncPath0(); + f.getUncPath0(); + + if (canon.equalsIgnoreCase(f.canon)) { + try { + ret = getAddress().equals(f.getAddress()); + } catch( UnknownHostException uhe ) { + ret = getServer().equalsIgnoreCase(f.getServer()); + } + return ret; + } + } + } + + return false; + } +/* + public boolean equals( Object obj ) { + return obj instanceof SmbFile && obj.hashCode() == hashCode(); + } +*/ + +/** + * Returns the string representation of this SmbFile object. This will + * be the same as the URL used to construct this SmbFile. + * This method will return the same value + * as getPath. + * + * @return The original URL representation of this SMB resource + * @throws SmbException + */ + + public String toString() { + return url.toString(); + } + +/* URLConnection implementation */ +/** + * This URLConnection method just returns the result of length(). + * + * @return the length of this file or 0 if it refers to a directory + */ + + public int getContentLength() { + try { + return (int)(length() & 0xFFFFFFFFL); + } catch( SmbException se ) { + } + return 0; + } + +/** + * This URLConnection method just returns the result of lastModified. + * + * @return the last modified data as milliseconds since Jan 1, 1970 + */ + public long getDate() { + try { + return lastModified(); + } catch( SmbException se ) { + } + return 0L; + } + +/** + * This URLConnection method just returns the result of lastModified. + * + * @return the last modified data as milliseconds since Jan 1, 1970 + */ + public long getLastModified() { + try { + return lastModified(); + } catch( SmbException se ) { + } + return 0L; + } + +/** + * This URLConnection method just returns a new SmbFileInputStream created with this file. + * + * @throws IOException thrown by SmbFileInputStream constructor + */ + public InputStream getInputStream() throws IOException { + return new SmbFileInputStream( this ); + } + +/** + * This URLConnection method just returns a new SmbFileOutputStream created with this file. + * + * @throws IOException thrown by SmbFileOutputStream constructor + */ + public OutputStream getOutputStream() throws IOException { + return new SmbFileOutputStream( this ); + } + + private void processAces(ACE[] aces, boolean resolveSids) throws IOException { + String server = getServerWithDfs(); + int ai; + + if (resolveSids) { + SID[] sids = new SID[aces.length]; + String[] names = null; + + for (ai = 0; ai < aces.length; ai++) { + sids[ai] = aces[ai].sid; + } + + for (int off = 0; off < sids.length; off += 10) { + int len = sids.length - off; + if (len > 64) + len = 64; + SID.resolveSids(server, auth, sids, off, len); + } + } else { + for (ai = 0; ai < aces.length; ai++) { + aces[ai].sid.origin_server = server; + aces[ai].sid.origin_auth = auth; + } + } + } +/** + * Return an array of Access Control Entry (ACE) objects representing + * the security descriptor associated with this file or directory. + * If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned. + * @param resolveSids Attempt to resolve the SIDs within each ACE form + * their numeric representation to their corresponding account names. + */ + public ACE[] getSecurity(boolean resolveSids) throws IOException { + int f; + ACE[] aces; + + f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 ); + + /* + * NtTrans Query Security Desc Request / Response + */ + + NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x04 ); + NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse(); + + try { + send( request, response ); + } finally { + close( f, 0L ); + } + + aces = response.securityDescriptor.aces; + if (aces != null) + processAces(aces, resolveSids); + + return aces; + } +/** + * Return an array of Access Control Entry (ACE) objects representing + * the share permissions on the share exporting this file or directory. + * If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned. + *

+ * Note that this is different from calling getSecurity on a + * share. There are actually two different ACLs for shares - the ACL on + * the share and the ACL on the folder being shared. + * Go to Computer Management + * > System Tools > Shared Folders > Shares and + * look at the Properties for a share. You will see two tabs - one + * for "Share Permissions" and another for "Security". These correspond to + * the ACLs returned by getShareSecurity and getSecurity + * respectively. + * @param resolveSids Attempt to resolve the SIDs within each ACE form + * their numeric representation to their corresponding account names. + */ + public ACE[] getShareSecurity(boolean resolveSids) throws IOException { + String p = url.getPath(); + MsrpcShareGetInfo rpc; + DcerpcHandle handle; + ACE[] aces; + + resolveDfs(null); + String server = getServerWithDfs(); + + rpc = new MsrpcShareGetInfo(server, tree.share); + handle = DcerpcHandle.getHandle("ncacn_np:" + server + "[\\PIPE\\srvsvc]", auth); + + try { + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, true); + aces = rpc.getSecurity(); + if (aces != null) + processAces(aces, resolveSids); + } finally { + try { + handle.close(); + } catch(IOException ioe) { + if (log.level >= 1) + ioe.printStackTrace(log); + } + } + + return aces; + } +/** + * Return an array of Access Control Entry (ACE) objects representing + * the security descriptor associated with this file or directory. + *

+ * Initially, the SIDs within each ACE will not be resolved however when + * getType(), getDomainName(), getAccountName(), + * or toString() is called, the names will attempt to be + * resolved. If the names cannot be resolved (e.g. due to temporary + * network failure), the said methods will return default values (usually + * S-X-Y-Z strings of fragments of). + *

+ * Alternatively getSecurity(true) may be used to resolve all + * SIDs together and detect network failures. + */ + public ACE[] getSecurity() throws IOException { + return getSecurity(false); + } + +} diff --git a/src/jcifs/smb/SmbFileFilter.java b/src/jcifs/smb/SmbFileFilter.java new file mode 100644 index 0000000..5dd2893 --- /dev/null +++ b/src/jcifs/smb/SmbFileFilter.java @@ -0,0 +1,23 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +public interface SmbFileFilter { + public boolean accept( SmbFile file ) throws SmbException; +} diff --git a/src/jcifs/smb/SmbFileInputStream.java b/src/jcifs/smb/SmbFileInputStream.java new file mode 100644 index 0000000..c92ecff --- /dev/null +++ b/src/jcifs/smb/SmbFileInputStream.java @@ -0,0 +1,247 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.net.URL; +import java.net.UnknownHostException; +import java.net.MalformedURLException; +import java.io.InputStream; +import java.io.IOException; +import java.io.InterruptedIOException; + +import jcifs.util.transport.TransportException; + +/** + * This InputStream can read bytes from a file on an SMB file server. Offsets are 64 bits. + */ + +public class SmbFileInputStream extends InputStream { + + private long fp; + private int readSize, openFlags, access; + private byte[] tmp = new byte[1]; + + SmbFile file; + +/** + * Creates an {@link java.io.InputStream} for reading bytes from a file on + * an SMB server addressed by the url parameter. See {@link + * jcifs.smb.SmbFile} for a detailed description and examples of the smb + * URL syntax. + * + * @param url An smb URL string representing the file to read from + */ + + public SmbFileInputStream( String url ) throws SmbException, MalformedURLException, UnknownHostException { + this( new SmbFile( url )); + } + +/** + * Creates an {@link java.io.InputStream} for reading bytes from a file on + * an SMB server represented by the {@link jcifs.smb.SmbFile} parameter. See + * {@link jcifs.smb.SmbFile} for a detailed description and examples of + * the smb URL syntax. + * + * @param file An SmbFile specifying the file to read from + */ + + public SmbFileInputStream( SmbFile file ) throws SmbException, MalformedURLException, UnknownHostException { + this( file, SmbFile.O_RDONLY ); + } + + SmbFileInputStream( SmbFile file, int openFlags ) throws SmbException, MalformedURLException, UnknownHostException { + this.file = file; + this.openFlags = openFlags & 0xFFFF; + this.access = (openFlags >>> 16) & 0xFFFF; + if (file.type != SmbFile.TYPE_NAMED_PIPE) { + file.open( openFlags, access, SmbFile.ATTR_NORMAL, 0 ); + this.openFlags &= ~(SmbFile.O_CREAT | SmbFile.O_TRUNC); + } else { + file.connect0(); + } + readSize = Math.min( file.tree.session.transport.rcv_buf_size - 70, + file.tree.session.transport.server.maxBufferSize - 70 ); + } + + protected IOException seToIoe(SmbException se) { + IOException ioe = se; + Throwable root = se.getRootCause(); + if (root instanceof TransportException) { + ioe = (TransportException)root; + root = ((TransportException)ioe).getRootCause(); + } + if (root instanceof InterruptedException) { + ioe = new InterruptedIOException(root.getMessage()); + ioe.initCause(root); + } + return ioe; + } + +/** + * Closes this input stream and releases any system resources associated with the stream. + * + * @throws IOException if a network error occurs + */ + + public void close() throws IOException { + try { + file.close(); + tmp = null; + } catch (SmbException se) { + throw seToIoe(se); + } + } + +/** + * Reads a byte of data from this input stream. + * + * @throws IOException if a network error occurs + */ + + public int read() throws IOException { + // need oplocks to cache otherwise use BufferedInputStream + if( read( tmp, 0, 1 ) == -1 ) { + return -1; + } + return tmp[0] & 0xFF; + } + +/** + * Reads up to b.length bytes of data from this input stream into an array of bytes. + * + * @throws IOException if a network error occurs + */ + + public int read( byte[] b ) throws IOException { + return read( b, 0, b.length ); + } + +/** + * Reads up to len bytes of data from this input stream into an array of bytes. + * + * @throws IOException if a network error occurs + */ + + public int read( byte[] b, int off, int len ) throws IOException { + return readDirect(b, off, len); + } + public int readDirect( byte[] b, int off, int len ) throws IOException { + if( len <= 0 ) { + return 0; + } + long start = fp; + + if( tmp == null ) { + throw new IOException( "Bad file descriptor" ); + } + // ensure file is open + file.open( openFlags, access, SmbFile.ATTR_NORMAL, 0 ); + + /* + * Read AndX Request / Response + */ + + if( file.log.level >= 4 ) + file.log.println( "read: fid=" + file.fid + ",off=" + off + ",len=" + len ); + + SmbComReadAndXResponse response = new SmbComReadAndXResponse( b, off ); + + if( file.type == SmbFile.TYPE_NAMED_PIPE ) { + response.responseTimeout = 0; + } + + int r, n; + do { + r = len > readSize ? readSize : len; + + if( file.log.level >= 4 ) + file.log.println( "read: len=" + len + ",r=" + r + ",fp=" + fp ); + + try { +SmbComReadAndX request = new SmbComReadAndX( file.fid, fp, r, null ); +if( file.type == SmbFile.TYPE_NAMED_PIPE ) { + request.minCount = request.maxCount = request.remaining = 1024; +} + file.send( request, response ); + } catch( SmbException se ) { + if( file.type == SmbFile.TYPE_NAMED_PIPE && + se.getNtStatus() == NtStatus.NT_STATUS_PIPE_BROKEN ) { + return -1; + } + throw seToIoe(se); + } + if(( n = response.dataLength ) <= 0 ) { + return (int)((fp - start) > 0L ? fp - start : -1); + } + fp += n; + len -= n; + response.off += n; + } while( len > 0 && n == r ); + + return (int)(fp - start); + } +/** + * This stream class is unbuffered. Therefore this method will always + * return 0 for streams connected to regular files. However, a + * stream created from a Named Pipe this method will query the server using a + * "peek named pipe" operation and return the number of available bytes + * on the server. + */ + public int available() throws IOException { + SmbNamedPipe pipe; + TransPeekNamedPipe req; + TransPeekNamedPipeResponse resp; + + if( file.type != SmbFile.TYPE_NAMED_PIPE ) { + return 0; + } + + try { + pipe = (SmbNamedPipe)file; + file.open(SmbFile.O_EXCL, pipe.pipeType & 0xFF0000, SmbFile.ATTR_NORMAL, 0 ); + + req = new TransPeekNamedPipe( file.unc, file.fid ); + resp = new TransPeekNamedPipeResponse( pipe ); + + pipe.send( req, resp ); + if( resp.status == TransPeekNamedPipeResponse.STATUS_DISCONNECTED || + resp.status == TransPeekNamedPipeResponse.STATUS_SERVER_END_CLOSED ) { + file.opened = false; + return 0; + } + return resp.available; + } catch (SmbException se) { + throw seToIoe(se); + } + } +/** + * Skip n bytes of data on this stream. This operation will not result + * in any IO with the server. Unlink InputStream value less than + * the one provided will not be returned if it exceeds the end of the file + * (if this is a problem let us know). + */ + public long skip( long n ) throws IOException { + if (n > 0) { + fp += n; + return n; + } + return 0; + } +} + diff --git a/src/jcifs/smb/SmbFileOutputStream.java b/src/jcifs/smb/SmbFileOutputStream.java new file mode 100644 index 0000000..bae0817 --- /dev/null +++ b/src/jcifs/smb/SmbFileOutputStream.java @@ -0,0 +1,259 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.net.URL; +import java.io.OutputStream; +import java.io.IOException; +import java.net.UnknownHostException; +import java.net.MalformedURLException; +import jcifs.util.LogStream; + +/** + * This OutputStream can write bytes to a file on an SMB file server. + */ + +public class SmbFileOutputStream extends OutputStream { + + private SmbFile file; + private boolean append, useNTSmbs; + private int openFlags, access, writeSize; + private long fp; + private byte[] tmp = new byte[1]; + private SmbComWriteAndX reqx; + private SmbComWriteAndXResponse rspx; + private SmbComWrite req; + private SmbComWriteResponse rsp; + +/** + * Creates an {@link java.io.OutputStream} for writing to a file + * on an SMB server addressed by the URL parameter. See {@link + * jcifs.smb.SmbFile} for a detailed description and examples of + * the smb URL syntax. + * + * @param url An smb URL string representing the file to write to + */ + + public SmbFileOutputStream( String url ) throws SmbException, MalformedURLException, UnknownHostException { + this( url, false ); + } + +/** + * Creates an {@link java.io.OutputStream} for writing bytes to a file on + * an SMB server represented by the {@link jcifs.smb.SmbFile} parameter. See + * {@link jcifs.smb.SmbFile} for a detailed description and examples of + * the smb URL syntax. + * + * @param file An SmbFile specifying the file to write to + */ + + public SmbFileOutputStream( SmbFile file ) throws SmbException, MalformedURLException, UnknownHostException { + this( file, false ); + } + +/** + * Creates an {@link java.io.OutputStream} for writing bytes to a file on an + * SMB server addressed by the URL parameter. See {@link jcifs.smb.SmbFile} + * for a detailed description and examples of the smb URL syntax. If the + * second argument is true, then bytes will be written to the + * end of the file rather than the beginning. + * + * @param url An smb URL string representing the file to write to + * @param append Append to the end of file + */ + + public SmbFileOutputStream( String url, boolean append ) throws SmbException, MalformedURLException, UnknownHostException { + this( new SmbFile( url ), append ); + } + +/** + * Creates an {@link java.io.OutputStream} for writing bytes to a file + * on an SMB server addressed by the SmbFile parameter. See + * {@link jcifs.smb.SmbFile} for a detailed description and examples of + * the smb URL syntax. If the second argument is true, then + * bytes will be written to the end of the file rather than the beginning. + * + * @param file An SmbFile representing the file to write to + * @param append Append to the end of file + */ + + public SmbFileOutputStream( SmbFile file, boolean append ) throws SmbException, MalformedURLException, UnknownHostException { + this( file, append, append ? SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_APPEND : + SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC ); + } +/** + * Creates an {@link java.io.OutputStream} for writing bytes to a file + * on an SMB server addressed by the SmbFile parameter. See + * {@link jcifs.smb.SmbFile} for a detailed description and examples of + * the smb URL syntax. +

+The second parameter specifies how the file should be shared. If +SmbFile.FILE_NO_SHARE is specified the client will +have exclusive access to the file. An additional open command +from jCIFS or another application will fail with the "file is being +accessed by another process" error. The FILE_SHARE_READ, +FILE_SHARE_WRITE, and FILE_SHARE_DELETE may be +combined with the bitwise OR '|' to specify that other peocesses may read, +write, and/or delete the file while the jCIFS user has the file open. + * + * @param url An smb URL representing the file to write to + * @param shareAccess File sharing flag: SmbFile.FILE_NOSHARE or any combination of SmbFile.FILE_READ, SmbFile.FILE_WRITE, and SmbFile.FILE_DELETE + */ + + public SmbFileOutputStream( String url, int shareAccess ) throws SmbException, MalformedURLException, UnknownHostException { + this( new SmbFile( url, "", null, shareAccess ), false ); + } + + SmbFileOutputStream( SmbFile file, boolean append, int openFlags ) throws SmbException, MalformedURLException, UnknownHostException { + this.file = file; + this.append = append; + this.openFlags = openFlags; + this.access = (openFlags >>> 16) & 0xFFFF; + if( append ) { + try { + fp = file.length(); + } catch( SmbAuthException sae ) { + throw sae; + } catch( SmbException se ) { + fp = 0L; + } + } + if( file instanceof SmbNamedPipe && file.unc.startsWith( "\\pipe\\" )) { + file.unc = file.unc.substring( 5 ); + file.send( new TransWaitNamedPipe( "\\pipe" + file.unc ), + new TransWaitNamedPipeResponse() ); + } + file.open( openFlags, access | SmbConstants.FILE_WRITE_DATA, SmbFile.ATTR_NORMAL, 0 ); + this.openFlags &= ~(SmbFile.O_CREAT | SmbFile.O_TRUNC); /* in case close and reopen */ + writeSize = file.tree.session.transport.snd_buf_size - 70; + + useNTSmbs = file.tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS ); + if( useNTSmbs ) { + reqx = new SmbComWriteAndX(); + rspx = new SmbComWriteAndXResponse(); + } else { + req = new SmbComWrite(); + rsp = new SmbComWriteResponse(); + } + } + +/** + * Closes this output stream and releases any system resources associated + * with it. + * + * @throws IOException if a network error occurs + */ + + public void close() throws IOException { + file.close(); + tmp = null; + } + +/** + * Writes the specified byte to this file output stream. + * + * @throws IOException if a network error occurs + */ + + public void write( int b ) throws IOException { + tmp[0] = (byte)b; + write( tmp, 0, 1 ); + } + +/** + * Writes b.length bytes from the specified byte array to this + * file output stream. + * + * @throws IOException if a network error occurs + */ + + public void write( byte[] b ) throws IOException { + write( b, 0, b.length ); + } + + public boolean isOpen() + { + return file.isOpen(); + } + void ensureOpen() throws IOException { + // ensure file is open + if( file.isOpen() == false ) { + file.open( openFlags, access | SmbConstants.FILE_WRITE_DATA, SmbFile.ATTR_NORMAL, 0 ); + if( append ) { + fp = file.length(); + } + } + } +/** + * Writes len bytes from the specified byte array starting at + * offset off to this file output stream. + * + * @param b The array + * @throws IOException if a network error occurs + */ + + public void write( byte[] b, int off, int len ) throws IOException { + if( file.isOpen() == false && file instanceof SmbNamedPipe ) { + file.send( new TransWaitNamedPipe( "\\pipe" + file.unc ), + new TransWaitNamedPipeResponse() ); + } + writeDirect( b, off, len, 0 ); + } +/** + * Just bypasses TransWaitNamedPipe - used by DCERPC bind. + */ + public void writeDirect( byte[] b, int off, int len, int flags ) throws IOException { + if( len <= 0 ) { + return; + } + + if( tmp == null ) { + throw new IOException( "Bad file descriptor" ); + } + ensureOpen(); + + if( file.log.level >= 4 ) + file.log.println( "write: fid=" + file.fid + ",off=" + off + ",len=" + len ); + + int w; + do { + w = len > writeSize ? writeSize : len; + if( useNTSmbs ) { + reqx.setParam( file.fid, fp, len - w, b, off, w ); +if ((flags & 1) != 0) { + reqx.setParam( file.fid, fp, len, b, off, w ); + reqx.writeMode = 0x8; +} else { + reqx.writeMode = 0; +} + file.send( reqx, rspx ); + fp += rspx.count; + len -= rspx.count; + off += rspx.count; + } else { + req.setParam( file.fid, fp, len - w, b, off, w ); + fp += rsp.count; + len -= rsp.count; + off += rsp.count; + file.send( req, rsp ); + } + } while( len > 0 ); + } +} + diff --git a/src/jcifs/smb/SmbFilenameFilter.java b/src/jcifs/smb/SmbFilenameFilter.java new file mode 100644 index 0000000..2e1cbd2 --- /dev/null +++ b/src/jcifs/smb/SmbFilenameFilter.java @@ -0,0 +1,23 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +public interface SmbFilenameFilter { + public boolean accept( SmbFile dir, String name ) throws SmbException; +} diff --git a/src/jcifs/smb/SmbNamedPipe.java b/src/jcifs/smb/SmbNamedPipe.java new file mode 100644 index 0000000..aa23921 --- /dev/null +++ b/src/jcifs/smb/SmbNamedPipe.java @@ -0,0 +1,195 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * "Paul Walker" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.net.URL; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.UnknownHostException; + +/** + * This class will allow a Java program to read and write data to Named + * Pipes and Transact NamedPipes. + * + *

There are three Win32 function calls provided by the Windows SDK + * that are important in the context of using jCIFS. They are: + * + *

    + *
  • CallNamedPipe A message-type pipe call that opens, + * writes to, reads from, and closes the pipe in a single operation. + *
  • TransactNamedPipe A message-type pipe call that + * writes to and reads from an existing pipe descriptor in one operation. + *
  • CreateFile, ReadFile, + * WriteFile, and CloseFile A byte-type pipe can + * be opened, written to, read from and closed using the standard Win32 + * file operations. + *
+ * + *

The jCIFS API maps all of these operations into the standard Java + * XxxputStream interface. A special PIPE_TYPE + * flags is necessary to distinguish which type of Named Pipe behavior + * is desired. + * + *

+ * + * + * + * + * + * + *
SmbNamedPipe Constructor Examples
Code SampleDescription
+ * new SmbNamedPipe( "smb://server/IPC$/PIPE/foo",
+ *         SmbNamedPipe.PIPE_TYPE_RDWR |
+ *         SmbNamedPipe.PIPE_TYPE_CALL );
+ * 
+ * Open the Named Pipe foo for reading and writing. The pipe will behave like the CallNamedPipe interface. + *
+ * new SmbNamedPipe( "smb://server/IPC$/foo",
+ *         SmbNamedPipe.PIPE_TYPE_RDWR |
+ *         SmbNamedPipe.PIPE_TYPE_TRANSACT );
+ * 
+ * Open the Named Pipe foo for reading and writing. The pipe will behave like the TransactNamedPipe interface. + *
+ * new SmbNamedPipe( "smb://server/IPC$/foo",
+ *         SmbNamedPipe.PIPE_TYPE_RDWR );
+ * 
+ * Open the Named Pipe foo for reading and writing. The pipe will + * behave as though the CreateFile, ReadFile, + * WriteFile, and CloseFile interface was + * being used. + *
+ * + *

See Using jCIFS to Connect to Win32 + * Named Pipes for a detailed description of how to use jCIFS with + * Win32 Named Pipe server processes. + * + */ + +public class SmbNamedPipe extends SmbFile { + + /** + * The pipe should be opened read-only. + */ + + public static final int PIPE_TYPE_RDONLY = O_RDONLY; + + /** + * The pipe should be opened only for writing. + */ + + public static final int PIPE_TYPE_WRONLY = O_WRONLY; + + /** + * The pipe should be opened for both reading and writing. + */ + + public static final int PIPE_TYPE_RDWR = O_RDWR; + + /** + * Pipe operations should behave like the CallNamedPipe Win32 Named Pipe function. + */ + + public static final int PIPE_TYPE_CALL = 0x0100; + + /** + * Pipe operations should behave like the TransactNamedPipe Win32 Named Pipe function. + */ + + public static final int PIPE_TYPE_TRANSACT = 0x0200; + + public static final int PIPE_TYPE_DCE_TRANSACT = 0x0200 | 0x0400; + + InputStream pipeIn; + OutputStream pipeOut; + int pipeType; + + /** + * Open the Named Pipe resource specified by the url + * parameter. The pipeType parameter should be at least one of + * the PIPE_TYPE flags combined with the bitwise OR + * operator |. See the examples listed above. + */ + + public SmbNamedPipe( String url, int pipeType ) + throws MalformedURLException, UnknownHostException { + super( url ); + this.pipeType = pipeType; + type = TYPE_NAMED_PIPE; + } + public SmbNamedPipe( String url, int pipeType, NtlmPasswordAuthentication auth ) + throws MalformedURLException, UnknownHostException { + super( url, auth ); + this.pipeType = pipeType; + type = TYPE_NAMED_PIPE; + } + public SmbNamedPipe( URL url, int pipeType, NtlmPasswordAuthentication auth ) + throws MalformedURLException, UnknownHostException { + super( url, auth ); + this.pipeType = pipeType; + type = TYPE_NAMED_PIPE; + } + + /** + * Return the InputStream used to read information + * from this pipe instance. Presumably data would first be written + * to the OutputStream associated with this Named + * Pipe instance although this is not a requirement (e.g. a + * read-only named pipe would write data to this stream on + * connection). Reading from this stream may block. Therefore it + * may be necessary that an addition thread be used to read and + * write to a Named Pipe. + */ + + public InputStream getNamedPipeInputStream() throws IOException { + if( pipeIn == null ) { + if(( pipeType & PIPE_TYPE_CALL ) == PIPE_TYPE_CALL || + ( pipeType & PIPE_TYPE_TRANSACT ) == PIPE_TYPE_TRANSACT ) { + pipeIn = new TransactNamedPipeInputStream( this ); + } else { + pipeIn = new SmbFileInputStream(this, + (pipeType & 0xFFFF00FF) | SmbFile.O_EXCL); + } + } + return pipeIn; + } + + /** + * Return the OutputStream used to write + * information to this pipe instance. The act of writing data + * to this stream will result in response data recieved in the + * InputStream associated with this Named Pipe + * instance (unless of course it does not elicite a response or the pipe is write-only). + */ + + public OutputStream getNamedPipeOutputStream() throws IOException { + if( pipeOut == null ) { + if(( pipeType & PIPE_TYPE_CALL ) == PIPE_TYPE_CALL || + ( pipeType & PIPE_TYPE_TRANSACT ) == PIPE_TYPE_TRANSACT ) { + pipeOut = new TransactNamedPipeOutputStream( this ); + } else { + pipeOut = new SmbFileOutputStream(this, false, + (pipeType & 0xFFFF00FF) | SmbFile.O_EXCL ); + } + } + return pipeOut; + } +} diff --git a/src/jcifs/smb/SmbRandomAccessFile.java b/src/jcifs/smb/SmbRandomAccessFile.java new file mode 100644 index 0000000..3fa2067 --- /dev/null +++ b/src/jcifs/smb/SmbRandomAccessFile.java @@ -0,0 +1,334 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.UnknownHostException; +import jcifs.util.Encdec; + +public class SmbRandomAccessFile implements DataOutput, DataInput { + + private static final int WRITE_OPTIONS = 0x0842; + + private SmbFile file; + private long fp; + private int openFlags, access = 0, readSize, writeSize, ch, options = 0; + private byte[] tmp = new byte[8]; + private SmbComWriteAndXResponse write_andx_resp = null; + + public SmbRandomAccessFile( String url, String mode, int shareAccess ) + throws SmbException, MalformedURLException, UnknownHostException { + this( new SmbFile( url, "", null, shareAccess ), mode ); + } + public SmbRandomAccessFile( SmbFile file, String mode ) + throws SmbException, MalformedURLException, UnknownHostException { + this.file = file; + if( mode.equals( "r" )) { + this.openFlags = SmbFile.O_CREAT | SmbFile.O_RDONLY; + } else if( mode.equals( "rw" )) { + this.openFlags = SmbFile.O_CREAT | SmbFile.O_RDWR | SmbFile.O_APPEND; + write_andx_resp = new SmbComWriteAndXResponse(); + options = WRITE_OPTIONS; + access = SmbConstants.FILE_READ_DATA | SmbConstants.FILE_WRITE_DATA; + } else { + throw new IllegalArgumentException( "Invalid mode" ); + } + file.open( openFlags, access, SmbFile.ATTR_NORMAL, options ); + readSize = file.tree.session.transport.rcv_buf_size - 70; + writeSize = file.tree.session.transport.snd_buf_size - 70; + fp = 0L; + } + + public int read() throws SmbException { + if( read( tmp, 0, 1 ) == -1 ) { + return -1; + } + return tmp[0] & 0xFF; + } + public int read( byte b[] ) throws SmbException { + return read( b, 0, b.length ); + } + public int read( byte b[], int off, int len ) throws SmbException { + if( len <= 0 ) { + return 0; + } + long start = fp; + + // ensure file is open + if( file.isOpen() == false ) { + file.open( openFlags, 0, SmbFile.ATTR_NORMAL, options ); + } + + int r, n; + SmbComReadAndXResponse response = new SmbComReadAndXResponse( b, off ); + do { + r = len > readSize ? readSize : len; + file.send( new SmbComReadAndX( file.fid, fp, r, null ), response ); + if(( n = response.dataLength ) <= 0 ) { + return (int)((fp - start) > 0L ? fp - start : -1); + } + fp += n; + len -= n; + response.off += n; + } while( len > 0 && n == r ); + + return (int)(fp - start); + } + public final void readFully( byte b[] ) throws SmbException { + readFully( b, 0, b.length ); + } + public final void readFully( byte b[], int off, int len ) throws SmbException { + int n = 0, count; + + do { + count = this.read( b, off + n, len - n ); + if( count < 0 ) throw new SmbException( "EOF" ); + n += count; + fp += count; + } while( n < len ); + } + public int skipBytes( int n ) throws SmbException { + if (n > 0) { + fp += n; + return n; + } + return 0; + } + + public void write( int b ) throws SmbException { + tmp[0] = (byte)b; + write( tmp, 0, 1 ); + } + public void write( byte b[] ) throws SmbException { + write( b, 0, b.length ); + } + public void write( byte b[], int off, int len ) throws SmbException { + if( len <= 0 ) { + return; + } + + // ensure file is open + if( file.isOpen() == false ) { + file.open( openFlags, 0, SmbFile.ATTR_NORMAL, options ); + } + + int w; + do { + w = len > writeSize ? writeSize : len; + file.send( new SmbComWriteAndX( file.fid, fp, len - w, b, off, w, null ), write_andx_resp ); + fp += write_andx_resp.count; + len -= write_andx_resp.count; + off += write_andx_resp.count; + } while( len > 0 ); + } + public long getFilePointer() throws SmbException { + return fp; + } + public void seek( long pos ) throws SmbException { + fp = pos; + } + public long length() throws SmbException { + return file.length(); + } + public void setLength( long newLength ) throws SmbException { + // ensure file is open + if( file.isOpen() == false ) { + file.open( openFlags, 0, SmbFile.ATTR_NORMAL, options ); + } + SmbComWriteResponse rsp = new SmbComWriteResponse(); + file.send( new SmbComWrite( file.fid, (int)(newLength & 0xFFFFFFFFL), 0, tmp, 0, 0 ), rsp ); + } + public void close() throws SmbException { + file.close(); + } + + public final boolean readBoolean() throws SmbException { + if((read( tmp, 0, 1 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return tmp[0] != (byte)0x00; + } + public final byte readByte() throws SmbException { + if((read( tmp, 0, 1 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return tmp[0]; + } + public final int readUnsignedByte() throws SmbException { + if((read( tmp, 0, 1 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return tmp[0] & 0xFF; + } + public final short readShort() throws SmbException { + if((read( tmp, 0, 2 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return Encdec.dec_uint16be( tmp, 0 ); + } + public final int readUnsignedShort() throws SmbException { + if((read( tmp, 0, 2 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return Encdec.dec_uint16be( tmp, 0 ) & 0xFFFF; + } + public final char readChar() throws SmbException { + if((read( tmp, 0, 2 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return (char)Encdec.dec_uint16be( tmp, 0 ); + } + public final int readInt() throws SmbException { + if((read( tmp, 0, 4 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return Encdec.dec_uint32be( tmp, 0 ); + } + public final long readLong() throws SmbException { + if((read( tmp, 0, 8 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return Encdec.dec_uint64be( tmp, 0 ); + } + public final float readFloat() throws SmbException { + if((read( tmp, 0, 4 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return Encdec.dec_floatbe( tmp, 0 ); + } + public final double readDouble() throws SmbException { + if((read( tmp, 0, 8 )) < 0 ) { + throw new SmbException( "EOF" ); + } + return Encdec.dec_doublebe( tmp, 0 ); + } + public final String readLine() throws SmbException { + StringBuffer input = new StringBuffer(); + int c = -1; + boolean eol = false; + + while (!eol) { + switch( c = read() ) { + case -1: + case '\n': + eol = true; + break; + case '\r': + eol = true; + long cur = fp; + if( read() != '\n' ) { + fp = cur; + } + break; + default: + input.append( (char)c ); + break; + } + } + + if ((c == -1) && (input.length() == 0)) { + return null; + } + + return input.toString(); + } + + public final String readUTF() throws SmbException { + int size = readUnsignedShort(); + byte[] b = new byte[size]; + read( b, 0, size ); + try { + return Encdec.dec_utf8( b, 0, size ); + } catch( IOException ioe ) { + throw new SmbException( "", ioe ); + } + } + public final void writeBoolean( boolean v ) throws SmbException { + tmp[0] = (byte)(v ? 1 : 0); + write( tmp, 0, 1 ); + } + public final void writeByte( int v ) throws SmbException { + tmp[0] = (byte)v; + write( tmp, 0, 1 ); + } + public final void writeShort( int v ) throws SmbException { + Encdec.enc_uint16be( (short)v, tmp, 0 ); + write( tmp, 0, 2 ); + } + public final void writeChar( int v ) throws SmbException { + Encdec.enc_uint16be( (short)v, tmp, 0 ); + write( tmp, 0, 2 ); + } + public final void writeInt( int v ) throws SmbException { + Encdec.enc_uint32be( v, tmp, 0 ); + write( tmp, 0, 4 ); + } + public final void writeLong( long v ) throws SmbException { + Encdec.enc_uint64be( v, tmp, 0 ); + write( tmp, 0, 8 ); + } + public final void writeFloat( float v ) throws SmbException { + Encdec.enc_floatbe( v, tmp, 0 ); + write( tmp, 0, 4 ); + } + public final void writeDouble( double v ) throws SmbException { + Encdec.enc_doublebe( v, tmp, 0 ); + write( tmp, 0, 8 ); + } + public final void writeBytes( String s ) throws SmbException { + byte[] b = s.getBytes(); + write( b, 0, b.length ); + } + public final void writeChars( String s ) throws SmbException { + int clen = s.length(); + int blen = 2 * clen; + byte[] b = new byte[blen]; + char[] c = new char[clen]; + s.getChars( 0, clen, c, 0 ); + for( int i = 0, j = 0; i < clen; i++ ) { + b[j++] = (byte)(c[i] >>> 8); + b[j++] = (byte)(c[i] >>> 0); + } + write( b, 0, blen ); + } + public final void writeUTF( String str ) throws SmbException { + int len = str.length(); + int ch, size = 0; + byte[] dst; + + for( int i = 0; i < len; i++ ) { + ch = str.charAt( i ); + size += ch > 0x07F ? (ch > 0x7FF ? 3 : 2) : 1; + } + dst = new byte[size]; + writeShort( size ); + try { + Encdec.enc_utf8( str, dst, 0, size ); + } catch( IOException ioe ) { + throw new SmbException( "", ioe ); + } + write( dst, 0, size ); + } +} + diff --git a/src/jcifs/smb/SmbSession.java b/src/jcifs/smb/SmbSession.java new file mode 100644 index 0000000..2ae651b --- /dev/null +++ b/src/jcifs/smb/SmbSession.java @@ -0,0 +1,479 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Vector; +import java.util.Enumeration; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.io.IOException; +import jcifs.Config; +import jcifs.UniAddress; +import jcifs.netbios.NbtAddress; +import jcifs.util.MD4; + +/** + * Update June 2009: This logon method of this class does not and never will support NTLMv2. JCIFS does not implement the acceptor side of NTLM authentication. It can only initiate NTLM authentication as a client. + */ + +public final class SmbSession { + + private static final String LOGON_SHARE = + Config.getProperty( "jcifs.smb.client.logonShare", null ); + private static final int LOOKUP_RESP_LIMIT = + Config.getInt( "jcifs.netbios.lookupRespLimit", 3 ); + private static final String DOMAIN = + Config.getProperty("jcifs.smb.client.domain", null); + private static final String USERNAME = + Config.getProperty("jcifs.smb.client.username", null); + private static final int CACHE_POLICY = + Config.getInt( "jcifs.netbios.cachePolicy", 60 * 10 ) * 60; /* 10 hours */ + + static NbtAddress[] dc_list = null; + static long dc_list_expiration; + static int dc_list_counter; + + private static NtlmChallenge interrogate( NbtAddress addr ) throws SmbException { + UniAddress dc = new UniAddress( addr ); + SmbTransport trans = SmbTransport.getSmbTransport( dc, 0 ); + if (USERNAME == null) { + trans.connect(); + if (SmbTransport.log.level >= 3) + SmbTransport.log.println( + "Default credentials (jcifs.smb.client.username/password)" + + " not specified. SMB signing may not work propertly." + + " Skipping DC interrogation." ); + } else { + SmbSession ssn = trans.getSmbSession( NtlmPasswordAuthentication.DEFAULT ); + ssn.getSmbTree( LOGON_SHARE, null ).treeConnect( null, null ); + } + return new NtlmChallenge( trans.server.encryptionKey, dc ); + } + public static NtlmChallenge getChallengeForDomain() + throws SmbException, UnknownHostException { + if( DOMAIN == null ) { + throw new SmbException( "A domain was not specified" ); + } +synchronized (DOMAIN) { + long now = System.currentTimeMillis(); + int retry = 1; + + do { + if (dc_list_expiration < now) { + NbtAddress[] list = NbtAddress.getAllByName( DOMAIN, 0x1C, null, null ); + dc_list_expiration = now + CACHE_POLICY * 1000L; + if (list != null && list.length > 0) { + dc_list = list; + } else { /* keep using the old list */ + dc_list_expiration = now + 1000 * 60 * 15; /* 15 min */ + if (SmbTransport.log.level >= 2) { + SmbTransport.log.println( "Failed to retrieve DC list from WINS" ); + } + } + } + + int max = Math.min( dc_list.length, LOOKUP_RESP_LIMIT ); + for (int j = 0; j < max; j++) { + int i = dc_list_counter++ % max; + if (dc_list[i] != null) { + try { + return interrogate( dc_list[i] ); + } catch (SmbException se) { + if (SmbTransport.log.level >= 2) { + SmbTransport.log.println( "Failed validate DC: " + dc_list[i] ); + if (SmbTransport.log.level > 2) + se.printStackTrace( SmbTransport.log ); + } + } + dc_list[i] = null; + } + } + + /* No DCs found, for retieval of list by expiring it and retry. + */ + dc_list_expiration = 0; + } while (retry-- > 0); + + dc_list_expiration = now + 1000 * 60 * 15; /* 15 min */ +} + + throw new UnknownHostException( + "Failed to negotiate with a suitable domain controller for " + DOMAIN ); + } + + public static byte[] getChallenge( UniAddress dc ) + throws SmbException, UnknownHostException { + return getChallenge(dc, 0); + } + + public static byte[] getChallenge( UniAddress dc, int port ) + throws SmbException, UnknownHostException { + SmbTransport trans = SmbTransport.getSmbTransport( dc, port ); + trans.connect(); + return trans.server.encryptionKey; + } +/** + * Authenticate arbitrary credentials represented by the + * NtlmPasswordAuthentication object against the domain controller + * specified by the UniAddress parameter. If the credentials are + * not accepted, an SmbAuthException will be thrown. If an error + * occurs an SmbException will be thrown. If the credentials are + * valid, the method will return without throwing an exception. See the + * last FAQ question. + *

+ * Update June 2009: This method does not support NTLMv2. JCIFS does not implement the acceptor side of NTLM authentication. It can only initiate NTLM authentication as a client. + *

+ * See also the jcifs.smb.client.logonShare property. + */ + public static void logon( UniAddress dc, + NtlmPasswordAuthentication auth ) throws SmbException { + logon(dc, 0, auth); + } + + public static void logon( UniAddress dc, int port, + NtlmPasswordAuthentication auth ) throws SmbException { + SmbTree tree = SmbTransport.getSmbTransport( dc, port ).getSmbSession( auth ).getSmbTree( LOGON_SHARE, null ); + if( LOGON_SHARE == null ) { + tree.treeConnect( null, null ); + } else { + Trans2FindFirst2 req = new Trans2FindFirst2( "\\", "*", SmbFile.ATTR_DIRECTORY ); + Trans2FindFirst2Response resp = new Trans2FindFirst2Response(); + tree.send( req, resp ); + } + } + + /* 0 - not connected + * 1 - connecting + * 2 - connected + * 3 - disconnecting + */ + int connectionState; + int uid; + Vector trees; + // Transport parameters allows trans to be removed from CONNECTIONS + private UniAddress address; + private int port, localPort; + private InetAddress localAddr; + + SmbTransport transport = null; + NtlmPasswordAuthentication auth; + long expiration; + String netbiosName = null; + + SmbSession( UniAddress address, int port, + InetAddress localAddr, int localPort, + NtlmPasswordAuthentication auth ) { + this.address = address; + this.port = port; + this.localAddr = localAddr; + this.localPort = localPort; + this.auth = auth; + trees = new Vector(); + connectionState = 0; + } + + synchronized SmbTree getSmbTree( String share, String service ) { + SmbTree t; + + if( share == null ) { + share = "IPC$"; + } + for( Enumeration e = trees.elements(); e.hasMoreElements(); ) { + t = (SmbTree)e.nextElement(); + if( t.matches( share, service )) { + return t; + } + } + t = new SmbTree( this, share, service ); + trees.addElement( t ); + return t; + } + boolean matches( NtlmPasswordAuthentication auth ) { + return this.auth == auth || this.auth.equals( auth ); + } + synchronized SmbTransport transport() { + if( transport == null ) { + transport = SmbTransport.getSmbTransport( address, port, localAddr, localPort, null ); + } + return transport; + } + void send( ServerMessageBlock request, + ServerMessageBlock response ) throws SmbException { +synchronized (transport()) { + if( response != null ) { + response.received = false; + } + + expiration = System.currentTimeMillis() + SmbTransport.SO_TIMEOUT; + sessionSetup( request, response ); + if( response != null && response.received ) { + return; + } + + if (request instanceof SmbComTreeConnectAndX) { + SmbComTreeConnectAndX tcax = (SmbComTreeConnectAndX)request; + if (netbiosName != null && tcax.path.endsWith("\\IPC$")) { + /* Some pipes may require that the hostname in the tree connect + * be the netbios name. So if we have the netbios server name + * from the NTLMSSP type 2 message, and the share is IPC$, we + * assert that the tree connect path uses the netbios hostname. + */ + tcax.path = "\\\\" + netbiosName + "\\IPC$"; + } + } + + request.uid = uid; + request.auth = auth; + try { + transport.send( request, response ); + } catch (SmbException se) { + if (request instanceof SmbComTreeConnectAndX) { + logoff(true); + } + request.digest = null; + throw se; + } +} + } + void sessionSetup( ServerMessageBlock andx, + ServerMessageBlock andxResponse ) throws SmbException { +synchronized (transport()) { + NtlmContext nctx = null; + SmbException ex = null; + SmbComSessionSetupAndX request; + SmbComSessionSetupAndXResponse response; + byte[] token = new byte[0]; + int state = 10; + + while (connectionState != 0) { + if (connectionState == 2 || connectionState == 3) // connected or disconnecting + return; + try { + transport.wait(); + } catch (InterruptedException ie) { + throw new SmbException(ie.getMessage(), ie); + } + } + connectionState = 1; // trying ... + + try { + transport.connect(); + + /* + * Session Setup And X Request / Response + */ + + if( transport.log.level >= 4 ) + transport.log.println( "sessionSetup: accountName=" + auth.username + ",primaryDomain=" + auth.domain ); + + /* We explicitly set uid to 0 here to prevent a new + * SMB_COM_SESSION_SETUP_ANDX from having it's uid set to an + * old value when the session is re-established. Otherwise a + * "The parameter is incorrect" error can occur. + */ + uid = 0; + + do { + switch (state) { + case 10: /* NTLM */ + if (auth != NtlmPasswordAuthentication.ANONYMOUS && + transport.hasCapability(SmbConstants.CAP_EXTENDED_SECURITY)) { + state = 20; /* NTLMSSP */ + break; + } + + request = new SmbComSessionSetupAndX( this, andx, auth ); + response = new SmbComSessionSetupAndXResponse( andxResponse ); + + /* Create SMB signature digest if necessary + * Only the first SMB_COM_SESSION_SETUP_ANX with non-null or + * blank password initializes signing. + */ + if (transport.isSignatureSetupRequired( auth )) { + if( auth.hashesExternal && NtlmPasswordAuthentication.DEFAULT_PASSWORD != NtlmPasswordAuthentication.BLANK ) { + /* preauthentication + */ + transport.getSmbSession( NtlmPasswordAuthentication.DEFAULT ).getSmbTree( LOGON_SHARE, null ).treeConnect( null, null ); + } else { + byte[] signingKey = auth.getSigningKey(transport.server.encryptionKey); + request.digest = new SigningDigest(signingKey, false); + } + } + + request.auth = auth; + + try { + transport.send( request, response ); + } catch (SmbAuthException sae) { + throw sae; + } catch (SmbException se) { + ex = se; + } + + if( response.isLoggedInAsGuest && + "GUEST".equalsIgnoreCase( auth.username ) == false && + transport.server.security != SmbConstants.SECURITY_SHARE) { + throw new SmbAuthException( NtStatus.NT_STATUS_LOGON_FAILURE ); + } + + if (ex != null) + throw ex; + + uid = response.uid; + + if( request.digest != null ) { + /* success - install the signing digest */ + transport.digest = request.digest; + } + + connectionState = 2; + + state = 0; + + break; + case 20: + if (nctx == null) { + boolean doSigning = (transport.flags2 & ServerMessageBlock.FLAGS2_SECURITY_SIGNATURES) != 0; + nctx = new NtlmContext(auth, doSigning); + } + + if (SmbTransport.log.level >= 4) + SmbTransport.log.println(nctx); + + if (nctx.isEstablished()) { + + netbiosName = nctx.getNetbiosName(); + + connectionState = 2; + + state = 0; + break; + } + + try { + token = nctx.initSecContext(token, 0, token.length); + } catch (SmbException se) { + /* We must close the transport or the server will be expecting a + * Type3Message. Otherwise, when we send a Type1Message it will return + * "Invalid parameter". + */ + try { transport.disconnect(true); } catch (IOException ioe) {} + uid = 0; + throw se; + } + + if (token != null) { + request = new SmbComSessionSetupAndX(this, null, token); + response = new SmbComSessionSetupAndXResponse(null); + + if (transport.isSignatureSetupRequired( auth )) { + byte[] signingKey = nctx.getSigningKey(); + if (signingKey != null) + request.digest = new SigningDigest(signingKey, true); + } + + request.uid = uid; + uid = 0; + + try { + transport.send( request, response ); + } catch (SmbAuthException sae) { + throw sae; + } catch (SmbException se) { + ex = se; + /* Apparently once a successfull NTLMSSP login occurs, the + * server will return "Access denied" even if a logoff is + * sent. Unfortunately calling disconnect() doesn't always + * actually shutdown the connection before other threads + * have committed themselves (e.g. InterruptTest example). + */ + try { transport.disconnect(true); } catch (Exception e) {} + } + + if( response.isLoggedInAsGuest && + "GUEST".equalsIgnoreCase( auth.username ) == false) { + throw new SmbAuthException( NtStatus.NT_STATUS_LOGON_FAILURE ); + } + + if (ex != null) + throw ex; + + uid = response.uid; + + if (request.digest != null) { + /* success - install the signing digest */ + transport.digest = request.digest; + } + + token = response.blob; + } + + break; + default: + throw new SmbException("Unexpected session setup state: " + state); + } + } while (state != 0); + } catch (SmbException se) { + logoff(true); + connectionState = 0; + throw se; + } finally { + transport.notifyAll(); + } +} + } + void logoff( boolean inError ) { +synchronized (transport()) { + + if (connectionState != 2) // not-connected + return; + connectionState = 3; // disconnecting + + netbiosName = null; + + for( Enumeration e = trees.elements(); e.hasMoreElements(); ) { + SmbTree t = (SmbTree)e.nextElement(); + t.treeDisconnect( inError ); + } + + if( !inError && transport.server.security != ServerMessageBlock.SECURITY_SHARE ) { + /* + * Logoff And X Request / Response + */ + + SmbComLogoffAndX request = new SmbComLogoffAndX( null ); + request.uid = uid; + try { + transport.send( request, null ); + } catch( SmbException se ) { + } + uid = 0; + } + + connectionState = 0; + transport.notifyAll(); +} + } + public String toString() { + return "SmbSession[accountName=" + auth.username + + ",primaryDomain=" + auth.domain + + ",uid=" + uid + + ",connectionState=" + connectionState + "]"; + } +} diff --git a/src/jcifs/smb/SmbShareInfo.java b/src/jcifs/smb/SmbShareInfo.java new file mode 100644 index 0000000..ad9b29b --- /dev/null +++ b/src/jcifs/smb/SmbShareInfo.java @@ -0,0 +1,82 @@ +/* jcifs smb client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.util.Hexdump; + +public class SmbShareInfo implements FileEntry { + + protected String netName; + protected int type; + protected String remark; + + public SmbShareInfo() { + } + public SmbShareInfo(String netName, int type, String remark) + { + this.netName = netName; + this.type = type; + this.remark = remark; + } + public String getName() { + return netName; + } + public int getType() { + /* 0x80000000 means hidden but SmbFile.isHidden() checks for $ at end + */ + switch (type & 0xFFFF) { + case 1: + return SmbFile.TYPE_PRINTER; + case 3: + return SmbFile.TYPE_NAMED_PIPE; + } + return SmbFile.TYPE_SHARE; + } + public int getAttributes() { + return SmbFile.ATTR_READONLY | SmbFile.ATTR_DIRECTORY; + } + public long createTime() { + return 0L; + } + public long lastModified() { + return 0L; + } + public long length() { + return 0L; + } + + public boolean equals(Object obj) { + if (obj instanceof SmbShareInfo) { + SmbShareInfo si = (SmbShareInfo)obj; + return netName.equals(si.netName); + } + return false; + } + public int hashCode() { + int hashCode = netName.hashCode(); + return hashCode; + } + + public String toString() { + return new String( "SmbShareInfo[" + + "netName=" + netName + + ",type=0x" + Hexdump.toHexString( type, 8 ) + + ",remark=" + remark + "]" ); + } +} diff --git a/src/jcifs/smb/SmbTransport.java b/src/jcifs/smb/SmbTransport.java new file mode 100644 index 0000000..fa504e5 --- /dev/null +++ b/src/jcifs/smb/SmbTransport.java @@ -0,0 +1,796 @@ +/* jcifs smb client library in Java + * Copyright (C) 2005 "Michael B. Allen" + * "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.*; +import java.net.*; +import java.util.*; + +import jcifs.*; +import jcifs.netbios.*; +import jcifs.util.*; +import jcifs.util.transport.*; +import jcifs.dcerpc.*; +import jcifs.dcerpc.msrpc.*; + +public class SmbTransport extends Transport implements SmbConstants { + + static final byte[] BUF = new byte[0xFFFF]; + static final SmbComNegotiate NEGOTIATE_REQUEST = new SmbComNegotiate(); + static LogStream log = LogStream.getInstance(); + static HashMap dfsRoots = null; + + static synchronized SmbTransport getSmbTransport( UniAddress address, int port ) { + return getSmbTransport( address, port, LADDR, LPORT, null ); + } + static synchronized SmbTransport getSmbTransport( UniAddress address, int port, + InetAddress localAddr, int localPort, String hostName ) { + SmbTransport conn; + + synchronized( CONNECTIONS ) { + if( SSN_LIMIT != 1 ) { + ListIterator iter = CONNECTIONS.listIterator(); + while( iter.hasNext() ) { + conn = (SmbTransport)iter.next(); + if( conn.matches( address, port, localAddr, localPort, hostName ) && + ( SSN_LIMIT == 0 || conn.sessions.size() < SSN_LIMIT )) { + return conn; + } + } + } + + conn = new SmbTransport( address, port, localAddr, localPort ); + CONNECTIONS.add( 0, conn ); + } + + return conn; + } + + class ServerData { + byte flags; + int flags2; + int maxMpxCount; + int maxBufferSize; + int sessionKey; + int capabilities; + String oemDomainName; + int securityMode; + int security; + boolean encryptedPasswords; + boolean signaturesEnabled; + boolean signaturesRequired; + int maxNumberVcs; + int maxRawSize; + long serverTime; + int serverTimeZone; + int encryptionKeyLength; + byte[] encryptionKey; + byte[] guid; + } + + InetAddress localAddr; + int localPort; + UniAddress address; + Socket socket; + int port, mid; + OutputStream out; + InputStream in; + byte[] sbuf = new byte[512]; /* small local buffer */ + SmbComBlankResponse key = new SmbComBlankResponse(); + long sessionExpiration = System.currentTimeMillis() + SO_TIMEOUT; + LinkedList referrals = new LinkedList(); + SigningDigest digest = null; + LinkedList sessions = new LinkedList(); + ServerData server = new ServerData(); + /* Negotiated values */ + int flags2 = FLAGS2; + int maxMpxCount = MAX_MPX_COUNT; + int snd_buf_size = SND_BUF_SIZE; + int rcv_buf_size = RCV_BUF_SIZE; + int capabilities = CAPABILITIES; + int sessionKey = 0x00000000; + boolean useUnicode = USE_UNICODE; + String tconHostName = null; + + SmbTransport( UniAddress address, int port, InetAddress localAddr, int localPort ) { + this.address = address; + this.port = port; + this.localAddr = localAddr; + this.localPort = localPort; + } + + synchronized SmbSession getSmbSession() { + return getSmbSession( new NtlmPasswordAuthentication( null, null, null )); + } + synchronized SmbSession getSmbSession( NtlmPasswordAuthentication auth ) { + SmbSession ssn; + long now; + + ListIterator iter = sessions.listIterator(); + while( iter.hasNext() ) { + ssn = (SmbSession)iter.next(); + if( ssn.matches( auth )) { + ssn.auth = auth; + return ssn; + } + } + + /* logoff old sessions */ + if (SO_TIMEOUT > 0 && sessionExpiration < (now = System.currentTimeMillis())) { + sessionExpiration = now + SO_TIMEOUT; + iter = sessions.listIterator(); + while( iter.hasNext() ) { + ssn = (SmbSession)iter.next(); + if( ssn.expiration < now ) { + ssn.logoff( false ); + } + } + } + + ssn = new SmbSession( address, port, localAddr, localPort, auth ); + ssn.transport = this; + sessions.add( ssn ); + + return ssn; + } + boolean matches( UniAddress address, int port, InetAddress localAddr, int localPort, String hostName ) { + if (hostName == null) + hostName = address.getHostName(); + return (this.tconHostName == null || hostName.equalsIgnoreCase(this.tconHostName)) && + address.equals( this.address ) && + (port == 0 || port == this.port || + /* port 139 is ok if 445 was requested */ + (port == 445 && this.port == 139)) && + (localAddr == this.localAddr || + (localAddr != null && + localAddr.equals( this.localAddr ))) && + localPort == this.localPort; + } + boolean hasCapability( int cap ) throws SmbException { + try { + connect( RESPONSE_TIMEOUT ); + } catch( IOException ioe ) { + throw new SmbException( ioe.getMessage(), ioe ); + } + return (capabilities & cap) == cap; + } + boolean isSignatureSetupRequired( NtlmPasswordAuthentication auth ) { + return ( flags2 & ServerMessageBlock.FLAGS2_SECURITY_SIGNATURES ) != 0 && + digest == null && + auth != NtlmPasswordAuthentication.NULL && + NtlmPasswordAuthentication.NULL.equals( auth ) == false; + } + + void ssn139() throws IOException { + Name calledName = new Name( address.firstCalledName(), 0x20, null ); + do { + if (localAddr == null) { + socket = new Socket( address.getHostAddress(), 139 ); + } else { + socket = new Socket( address.getHostAddress(), 139, localAddr, localPort ); + } + socket.setSoTimeout( SO_TIMEOUT ); + out = socket.getOutputStream(); + in = socket.getInputStream(); + + SessionServicePacket ssp = new SessionRequestPacket( calledName, + NbtAddress.getLocalName() ); + out.write( sbuf, 0, ssp.writeWireFormat( sbuf, 0 )); + if (readn( in, sbuf, 0, 4 ) < 4) { + try { + socket.close(); + } catch(IOException ioe) { + } + throw new SmbException( "EOF during NetBIOS session request" ); + } + switch( sbuf[0] & 0xFF ) { + case SessionServicePacket.POSITIVE_SESSION_RESPONSE: + if( log.level >= 4 ) + log.println( "session established ok with " + address ); + return; + case SessionServicePacket.NEGATIVE_SESSION_RESPONSE: + int errorCode = (int)( in.read() & 0xFF ); + switch (errorCode) { + case NbtException.CALLED_NOT_PRESENT: + case NbtException.NOT_LISTENING_CALLED: + socket.close(); + break; + default: + disconnect( true ); + throw new NbtException( NbtException.ERR_SSN_SRVC, errorCode ); + } + break; + case -1: + disconnect( true ); + throw new NbtException( NbtException.ERR_SSN_SRVC, + NbtException.CONNECTION_REFUSED ); + default: + disconnect( true ); + throw new NbtException( NbtException.ERR_SSN_SRVC, 0 ); + } + } while(( calledName.name = address.nextCalledName()) != null ); + + throw new IOException( "Failed to establish session with " + address ); + } + private void negotiate( int port, ServerMessageBlock resp ) throws IOException { + /* We cannot use Transport.sendrecv() yet because + * the Transport thread is not setup until doConnect() + * returns and we want to supress all communication + * until we have properly negotiated. + */ + synchronized (sbuf) { + /* If jcifs.netbios.hostname is set this *probably* means there + * is a policy regarding which hosts a user can connect from. This + * requires communicating over port 139 rather than 445. + */ + if (false && NETBIOS_HOSTNAME != null && NETBIOS_HOSTNAME.equals( "" ) == false) { + port = 139; + } + if (port == 139) { + ssn139(); + } else { + if (port == 0) + port = DEFAULT_PORT; // 445 + if (localAddr == null) { + socket = new Socket( address.getHostAddress(), port ); + } else { + socket = new Socket( address.getHostAddress(), port, localAddr, localPort ); + } + socket.setSoTimeout( SO_TIMEOUT ); + out = socket.getOutputStream(); + in = socket.getInputStream(); + } + + if (++mid == 32000) mid = 1; + NEGOTIATE_REQUEST.mid = mid; + int n = NEGOTIATE_REQUEST.encode( sbuf, 4 ); + Encdec.enc_uint32be( n & 0xFFFF, sbuf, 0 ); /* 4 byte ssn msg header */ + + if (log.level >= 4) { + log.println( NEGOTIATE_REQUEST ); + if (log.level >= 6) { + Hexdump.hexdump( log, sbuf, 4, n ); + } + } + + out.write( sbuf, 0, 4 + n ); + out.flush(); + /* Note the Transport thread isn't running yet so we can + * read from the socket here. + */ + if (peekKey() == null) /* try to read header */ + throw new IOException( "transport closed in negotiate" ); + int size = Encdec.dec_uint16be( sbuf, 2 ) & 0xFFFF; + if (size < 33 || (4 + size) > sbuf.length ) { + throw new IOException( "Invalid payload size: " + size ); + } + readn( in, sbuf, 4 + 32, size - 32 ); + resp.decode( sbuf, 4 ); + + if (log.level >= 4) { + log.println( resp ); + if (log.level >= 6) { + Hexdump.hexdump( log, sbuf, 4, n ); + } + } + } + } + public void connect() throws SmbException { + try { + super.connect( RESPONSE_TIMEOUT ); + } catch( TransportException te ) { + throw new SmbException( "Failed to connect: " + address, te ); + } + } + protected void doConnect() throws IOException { + /* + * Negotiate Protocol Request / Response + */ + + SmbComNegotiateResponse resp = new SmbComNegotiateResponse( server ); + try { + negotiate( port, resp ); + } catch( ConnectException ce ) { + port = (port == 0 || port == DEFAULT_PORT) ? 139 : DEFAULT_PORT; + negotiate( port, resp ); + } catch( NoRouteToHostException nr ) { + port = (port == 0 || port == DEFAULT_PORT) ? 139 : DEFAULT_PORT; + negotiate( port, resp ); + } + + if( resp.dialectIndex > 10 ) { + throw new SmbException( "This client does not support the negotiated dialect." ); + } + if ((server.capabilities & CAP_EXTENDED_SECURITY) != CAP_EXTENDED_SECURITY && + server.encryptionKeyLength != 8 && + LM_COMPATIBILITY == 0) { + throw new SmbException("Unexpected encryption key length: " + server.encryptionKeyLength); + } + + /* Adjust negotiated values */ + + tconHostName = address.getHostName(); + if (server.signaturesRequired || (server.signaturesEnabled && SIGNPREF)) { + flags2 |= ServerMessageBlock.FLAGS2_SECURITY_SIGNATURES; + } else { + flags2 &= 0xFFFF ^ ServerMessageBlock.FLAGS2_SECURITY_SIGNATURES; + } + maxMpxCount = Math.min( maxMpxCount, server.maxMpxCount ); + if (maxMpxCount < 1) maxMpxCount = 1; + snd_buf_size = Math.min( snd_buf_size, server.maxBufferSize ); + capabilities &= server.capabilities; + if ((server.capabilities & CAP_EXTENDED_SECURITY) == CAP_EXTENDED_SECURITY) + capabilities |= CAP_EXTENDED_SECURITY; // & doesn't copy high bit + + if ((capabilities & ServerMessageBlock.CAP_UNICODE) == 0) { + // server doesn't want unicode + if (FORCE_UNICODE) { + capabilities |= ServerMessageBlock.CAP_UNICODE; + } else { + useUnicode = false; + flags2 &= 0xFFFF ^ ServerMessageBlock.FLAGS2_UNICODE; + } + } + } + protected void doDisconnect( boolean hard ) throws IOException { + ListIterator iter = sessions.listIterator(); + while (iter.hasNext()) { + SmbSession ssn = (SmbSession)iter.next(); + ssn.logoff( hard ); + } + socket.shutdownOutput(); + out.close(); + in.close(); + socket.close(); + digest = null; + } + + protected void makeKey( Request request ) throws IOException { + /* The request *is* the key */ + if (++mid == 32000) mid = 1; + ((ServerMessageBlock)request).mid = mid; + } + protected Request peekKey() throws IOException { + int n; + do { + if ((n = readn( in, sbuf, 0, 4 )) < 4) + return null; + } while (sbuf[0] == (byte)0x85); /* Dodge NetBIOS keep-alive */ + /* read smb header */ + if ((n = readn( in, sbuf, 4, 32 )) < 32) + return null; + if (log.level >= 4) { + log.println( "New data read: " + this ); + jcifs.util.Hexdump.hexdump( log, sbuf, 4, 32 ); + } + + for ( ;; ) { + /* 01234567 + * 00SSFSMB + * 0 - 0's + * S - size of payload + * FSMB - 0xFF SMB magic # + */ + + if (sbuf[0] == (byte)0x00 && + sbuf[1] == (byte)0x00 && + sbuf[4] == (byte)0xFF && + sbuf[5] == (byte)'S' && + sbuf[6] == (byte)'M' && + sbuf[7] == (byte)'B') { + break; /* all good */ + } + /* out of phase maybe? */ + /* inch forward 1 byte and try again */ + for (int i = 0; i < 35; i++) { + sbuf[i] = sbuf[i + 1]; + } + int b; + if ((b = in.read()) == -1) return null; + sbuf[35] = (byte)b; + } + + key.mid = Encdec.dec_uint16le( sbuf, 34 ) & 0xFFFF; + + /* Unless key returned is null or invalid Transport.loop() always + * calls doRecv() after and no one else but the transport thread + * should call doRecv(). Therefore it is ok to expect that the data + * in sbuf will be preserved for copying into BUF in doRecv(). + */ + + return key; + } + + protected void doSend( Request request ) throws IOException { + synchronized (BUF) { + ServerMessageBlock smb = (ServerMessageBlock)request; + int n = smb.encode( BUF, 4 ); + Encdec.enc_uint32be( n & 0xFFFF, BUF, 0 ); /* 4 byte session message header */ + if (log.level >= 4) { + do { + log.println( smb ); + } while (smb instanceof AndXServerMessageBlock && + (smb = ((AndXServerMessageBlock)smb).andx) != null); + if (log.level >= 6) { + Hexdump.hexdump( log, BUF, 4, n ); + } + } + out.write( BUF, 0, 4 + n ); + } + } + protected void doSend0( Request request ) throws IOException { + try { + doSend( request ); + } catch( IOException ioe ) { + if (log.level > 2) + ioe.printStackTrace( log ); + try { + disconnect( true ); + } catch( IOException ioe2 ) { + ioe2.printStackTrace( log ); + } + throw ioe; + } + } + + protected void doRecv( Response response ) throws IOException { + ServerMessageBlock resp = (ServerMessageBlock)response; + resp.useUnicode = useUnicode; + resp.extendedSecurity = (capabilities & CAP_EXTENDED_SECURITY) == CAP_EXTENDED_SECURITY; + + synchronized (BUF) { + System.arraycopy( sbuf, 0, BUF, 0, 4 + HEADER_LENGTH ); + int size = Encdec.dec_uint16be( BUF, 2 ) & 0xFFFF; + if (size < (HEADER_LENGTH + 1) || (4 + size) > rcv_buf_size ) { + throw new IOException( "Invalid payload size: " + size ); + } + int errorCode = Encdec.dec_uint32le( BUF, 9 ) & 0xFFFFFFFF; + if (resp.command == ServerMessageBlock.SMB_COM_READ_ANDX && + (errorCode == 0 || + errorCode == 0x80000005)) { // overflow indicator normal for pipe + SmbComReadAndXResponse r = (SmbComReadAndXResponse)resp; + int off = HEADER_LENGTH; + /* WordCount thru dataOffset always 27 */ + readn( in, BUF, 4 + off, 27 ); off += 27; + resp.decode( BUF, 4 ); + /* EMC can send pad w/o data */ + int pad = r.dataOffset - off; + if (r.byteCount > 0 && pad > 0 && pad < 4) + readn( in, BUF, 4 + off, pad); + + if (r.dataLength > 0) + readn( in, r.b, r.off, r.dataLength ); /* read direct */ + } else { + readn( in, BUF, 4 + 32, size - 32 ); + resp.decode( BUF, 4 ); + if (resp instanceof SmbComTransactionResponse) { + ((SmbComTransactionResponse)resp).nextElement(); + } + } + + /* Verification fails (w/ W2K3 server at least) if status is not 0. This + * suggests MS doesn't compute the signature (correctly) for error responses + * (perhaps for DOS reasons). + */ + if (digest != null && resp.errorCode == 0) { + digest.verify( BUF, 4, resp ); + } + + if (log.level >= 4) { + log.println( response ); + if (log.level >= 6) { + Hexdump.hexdump( log, BUF, 4, size ); + } + } + } + } + protected void doSkip() throws IOException { + int size = Encdec.dec_uint16be( sbuf, 2 ) & 0xFFFF; + if (size < 33 || (4 + size) > rcv_buf_size ) { + /* log message? */ + in.skip( in.available() ); + } else { + in.skip( size - 32 ); + } + } + void checkStatus( ServerMessageBlock req, ServerMessageBlock resp ) throws SmbException { + resp.errorCode = SmbException.getStatusByCode( resp.errorCode ); + switch( resp.errorCode ) { + case NtStatus.NT_STATUS_OK: + break; + case NtStatus.NT_STATUS_ACCESS_DENIED: + case NtStatus.NT_STATUS_WRONG_PASSWORD: + case NtStatus.NT_STATUS_LOGON_FAILURE: + case NtStatus.NT_STATUS_ACCOUNT_RESTRICTION: + case NtStatus.NT_STATUS_INVALID_LOGON_HOURS: + case NtStatus.NT_STATUS_INVALID_WORKSTATION: + case NtStatus.NT_STATUS_PASSWORD_EXPIRED: + case NtStatus.NT_STATUS_ACCOUNT_DISABLED: + case NtStatus.NT_STATUS_ACCOUNT_LOCKED_OUT: + case NtStatus.NT_STATUS_TRUSTED_DOMAIN_FAILURE: + throw new SmbAuthException( resp.errorCode ); + case NtStatus.NT_STATUS_PATH_NOT_COVERED: + if( req.auth == null ) { + throw new SmbException( resp.errorCode, null ); + } + + DfsReferral dr = getDfsReferrals(req.auth, req.path, 1); + if (dr == null) + throw new SmbException(resp.errorCode, null); + + SmbFile.dfs.insert(req.path, dr); + throw dr; + case 0x80000005: /* STATUS_BUFFER_OVERFLOW */ + break; /* normal for DCERPC named pipes */ + case NtStatus.NT_STATUS_MORE_PROCESSING_REQUIRED: + break; /* normal for NTLMSSP */ + default: + throw new SmbException( resp.errorCode, null ); + } + if (resp.verifyFailed) { + throw new SmbException( "Signature verification failed." ); + } + } + void send( ServerMessageBlock request, ServerMessageBlock response ) throws SmbException { + + connect(); /* must negotiate before we can test flags2, useUnicode, etc */ + + request.flags2 |= flags2; + request.useUnicode = useUnicode; + request.response = response; /* needed by sign */ + if (request.digest == null) + request.digest = digest; /* for sign called in encode */ + + try { + if (response == null) { + doSend0( request ); + return; + } else if (request instanceof SmbComTransaction) { + response.command = request.command; + SmbComTransaction req = (SmbComTransaction)request; + SmbComTransactionResponse resp = (SmbComTransactionResponse)response; + + req.maxBufferSize = snd_buf_size; + resp.reset(); + + try { + BufferCache.getBuffers( req, resp ); + + /* + * First request w/ interim response + */ + + req.nextElement(); + if (req.hasMoreElements()) { + SmbComBlankResponse interim = new SmbComBlankResponse(); + super.sendrecv( req, interim, RESPONSE_TIMEOUT ); + if (interim.errorCode != 0) { + checkStatus( req, interim ); + } + req.nextElement(); + } else { + makeKey( req ); + } + + synchronized (this) { + response.received = false; + resp.isReceived = false; + try { + response_map.put( req, resp ); + + /* + * Send multiple fragments + */ + + do { + doSend0( req ); + } while( req.hasMoreElements() && req.nextElement() != null ); + + /* + * Receive multiple fragments + */ + + long timeout = RESPONSE_TIMEOUT; + resp.expiration = System.currentTimeMillis() + timeout; + while( resp.hasMoreElements() ) { + wait( timeout ); + timeout = resp.expiration - System.currentTimeMillis(); + if (timeout <= 0) { + throw new TransportException( this + + " timedout waiting for response to " + + req ); + } + } + if (response.errorCode != 0) { + checkStatus( req, resp ); + } + } catch( InterruptedException ie ) { + throw new TransportException( ie ); + } finally { + response_map.remove( req ); + } + } + } finally { + BufferCache.releaseBuffer( req.txn_buf ); + BufferCache.releaseBuffer( resp.txn_buf ); + } + + } else { + response.command = request.command; + super.sendrecv( request, response, RESPONSE_TIMEOUT ); + } + } catch( SmbException se ) { + throw se; + } catch( IOException ioe ) { + throw new SmbException( ioe.getMessage(), ioe ); + } + + checkStatus( request, response ); + } + public String toString() { + return super.toString() + "[" + address + ":" + port + "]"; + } + + /* DFS */ + + /* Split DFS path like \fs1.example.com\root5\link2\foo\bar.txt into at + * most 3 components (not including the first index which is always empty): + * result[0] = "" + * result[1] = "fs1.example.com" + * result[2] = "root5" + * result[3] = "link2\foo\bar.txt" + */ + void dfsPathSplit(String path, String[] result) + { + int ri = 0, rlast = result.length - 1; + int i = 0, b = 0, len = path.length(); + + do { + if (ri == rlast) { + result[rlast] = path.substring(b); + return; + } + if (i == len || path.charAt(i) == '\\') { + result[ri++] = path.substring(b, i); + b = i + 1; + } + } while (i++ < len); + + while (ri < result.length) { + result[ri++] = ""; + } + } + DfsReferral getDfsReferrals(NtlmPasswordAuthentication auth, + String path, + int rn) throws SmbException { + SmbTree ipc = getSmbSession( auth ).getSmbTree( "IPC$", null ); + Trans2GetDfsReferralResponse resp = new Trans2GetDfsReferralResponse(); + ipc.send( new Trans2GetDfsReferral( path ), resp ); + + if (resp.numReferrals == 0) { + return null; + } else if (rn == 0 || resp.numReferrals < rn) { + rn = resp.numReferrals; + } + + DfsReferral dr = new DfsReferral(); + + String[] arr = new String[4]; + long expiration = System.currentTimeMillis() + Dfs.TTL * 1000; + + int di = 0; + for ( ;; ) { + /* NTLM HTTP Authentication must be re-negotiated + * with challenge from 'server' to access DFS vol. */ + dr.resolveHashes = auth.hashesExternal; + dr.ttl = resp.referrals[di].ttl; + dr.expiration = expiration; + if (path.equals("")) { + dr.server = resp.referrals[di].path.substring(1).toLowerCase(); + } else { + dfsPathSplit(resp.referrals[di].node, arr); + dr.server = arr[1]; + dr.share = arr[2]; + dr.path = arr[3]; + } + dr.pathConsumed = resp.pathConsumed; + + di++; + if (di == rn) + break; + + dr.append(new DfsReferral()); + dr = dr.next; + } + + return dr.next; + } + DfsReferral[] __getDfsReferrals(NtlmPasswordAuthentication auth, + String path, + int rn) throws SmbException { + SmbTree ipc = getSmbSession( auth ).getSmbTree( "IPC$", null ); + Trans2GetDfsReferralResponse resp = new Trans2GetDfsReferralResponse(); + ipc.send( new Trans2GetDfsReferral( path ), resp ); + + if (rn == 0 || resp.numReferrals < rn) { + rn = resp.numReferrals; + } + + DfsReferral[] drs = new DfsReferral[rn]; + String[] arr = new String[4]; + long expiration = System.currentTimeMillis() + Dfs.TTL * 1000; + + for (int di = 0; di < drs.length; di++) { + DfsReferral dr = new DfsReferral(); + /* NTLM HTTP Authentication must be re-negotiated + * with challenge from 'server' to access DFS vol. */ + dr.resolveHashes = auth.hashesExternal; + dr.ttl = resp.referrals[di].ttl; + dr.expiration = expiration; + if (path.equals("")) { + dr.server = resp.referrals[di].path.substring(1).toLowerCase(); + } else { + dfsPathSplit(resp.referrals[di].node, arr); + dr.server = arr[1]; + dr.share = arr[2]; + dr.path = arr[3]; + } + dr.pathConsumed = resp.pathConsumed; + drs[di] = dr; + } + + return drs; + } + +// FileEntry[] getDfsRoots(String domainName, NtlmPasswordAuthentication auth) throws IOException { +// MsrpcDfsRootEnum rpc; +// DcerpcHandle handle = null; +// +// /* Procedure: +// * Lookup a DC in the target domain +// * Ask the DC for a referral for the domain (e.g. "\example.com") +// * Do NetrDfsEnumEx on the server returned in the referral to +// * get roots in target domain +// */ +// +// UniAddress dc = UniAddress.getByName(domainName); +// SmbTransport trans = SmbTransport.getSmbTransport(dc, 0); +// DfsReferral[] dr = trans.getDfsReferrals(auth, "\\" + domainName, 1); +// +// handle = DcerpcHandle.getHandle("ncacn_np:" + +// UniAddress.getByName(dr[0].server).getHostAddress() + +// "[\\PIPE\\netdfs]", auth); +// try { +// rpc = new MsrpcDfsRootEnum(domainName); +// handle.sendrecv(rpc); +// if (rpc.retval != 0) +// throw new SmbException(rpc.retval, true); +// return rpc.getEntries(); +// } finally { +// try { +// handle.close(); +// } catch(IOException ioe) { +// if (log.level >= 4) +// ioe.printStackTrace(log); +// } +// } +// } +} + diff --git a/src/jcifs/smb/SmbTree.java b/src/jcifs/smb/SmbTree.java new file mode 100644 index 0000000..45a0d5c --- /dev/null +++ b/src/jcifs/smb/SmbTree.java @@ -0,0 +1,224 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.IOException; +import java.net.UnknownHostException; +import jcifs.UniAddress; +import jcifs.netbios.NbtAddress; +import jcifs.Config; + +class SmbTree { + + private static int tree_conn_counter; + + /* 0 - not connected + * 1 - connecting + * 2 - connected + * 3 - disconnecting + */ + int connectionState; + int tid; + + String share; + String service = "?????"; + String service0; + SmbSession session; + boolean inDfs, inDomainDfs; + int tree_num; // used by SmbFile.isOpen + + SmbTree( SmbSession session, String share, String service ) { + this.session = session; + this.share = share.toUpperCase(); + if( service != null && service.startsWith( "??" ) == false ) { + this.service = service; + } + this.service0 = this.service; + this.connectionState = 0; + } + + boolean matches( String share, String service ) { + return this.share.equalsIgnoreCase( share ) && + ( service == null || service.startsWith( "??" ) || + this.service.equalsIgnoreCase( service )); + } + public boolean equals(Object obj) { + if (obj instanceof SmbTree) { + SmbTree tree = (SmbTree)obj; + return matches(tree.share, tree.service); + } + return false; + } + void send( ServerMessageBlock request, + ServerMessageBlock response ) throws SmbException { +synchronized (session.transport()) { + if( response != null ) { + response.received = false; + } + treeConnect( request, response ); + if( request == null || (response != null && response.received )) { + return; + } + if( service.equals( "A:" ) == false ) { + switch( request.command ) { + case ServerMessageBlock.SMB_COM_OPEN_ANDX: + case ServerMessageBlock.SMB_COM_NT_CREATE_ANDX: + case ServerMessageBlock.SMB_COM_READ_ANDX: + case ServerMessageBlock.SMB_COM_WRITE_ANDX: + case ServerMessageBlock.SMB_COM_CLOSE: + case ServerMessageBlock.SMB_COM_TREE_DISCONNECT: + break; + case ServerMessageBlock.SMB_COM_TRANSACTION: + case ServerMessageBlock.SMB_COM_TRANSACTION2: + switch( ((SmbComTransaction)request).subCommand & 0xFF ) { + case SmbComTransaction.NET_SHARE_ENUM: + case SmbComTransaction.NET_SERVER_ENUM2: + case SmbComTransaction.NET_SERVER_ENUM3: + case SmbComTransaction.TRANS_PEEK_NAMED_PIPE: + case SmbComTransaction.TRANS_WAIT_NAMED_PIPE: + case SmbComTransaction.TRANS_CALL_NAMED_PIPE: + case SmbComTransaction.TRANS_TRANSACT_NAMED_PIPE: + case SmbComTransaction.TRANS2_GET_DFS_REFERRAL: + break; + default: + throw new SmbException( "Invalid operation for " + service + " service" ); + } + break; + default: + throw new SmbException( "Invalid operation for " + service + " service" + request ); + } + } + request.tid = tid; + if( inDfs && !service.equals("IPC") && request.path != null && request.path.length() > 0 ) { + /* When DFS is in action all request paths are + * full UNC paths minus the first backslash like + * \server\share\path\to\file + * as opposed to normally + * \path\to\file + */ + request.flags2 = ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS; + request.path = '\\' + session.transport().tconHostName + '\\' + share + request.path; + } + try { + session.send( request, response ); + } catch( SmbException se ) { + if (se.getNtStatus() == se.NT_STATUS_NETWORK_NAME_DELETED) { + /* Someone removed the share while we were + * connected. Bastards! Disconnect this tree + * so that it reconnects cleanly should the share + * reappear in this client's lifetime. + */ + treeDisconnect( true ); + } + throw se; + } +} + } + void treeConnect( ServerMessageBlock andx, + ServerMessageBlock andxResponse ) throws SmbException { + +synchronized (session.transport()) { + String unc; + + while (connectionState != 0) { + if (connectionState == 2 || connectionState == 3) // connected or disconnecting + return; + try { + session.transport.wait(); + } catch (InterruptedException ie) { + throw new SmbException(ie.getMessage(), ie); + } + } + connectionState = 1; // trying ... + + try { + /* The hostname to use in the path is only known for + * sure if the NetBIOS session has been successfully + * established. + */ + + session.transport.connect(); + + unc = "\\\\" + session.transport.tconHostName + '\\' + share; + + /* IBM iSeries doesn't like specifying a service. Always reset + * the service to whatever was determined in the constructor. + */ + service = service0; + + /* + * Tree Connect And X Request / Response + */ + + if( session.transport.log.level >= 4 ) + session.transport.log.println( "treeConnect: unc=" + unc + ",service=" + service ); + + SmbComTreeConnectAndXResponse response = + new SmbComTreeConnectAndXResponse( andxResponse ); + SmbComTreeConnectAndX request = + new SmbComTreeConnectAndX( session, unc, service, andx ); + session.send( request, response ); + + tid = response.tid; + service = response.service; + inDfs = response.shareIsInDfs; + tree_num = tree_conn_counter++; + + connectionState = 2; // connected + } catch (SmbException se) { + treeDisconnect(true); + connectionState = 0; + throw se; + } +} + } + void treeDisconnect( boolean inError ) { +synchronized (session.transport()) { + + if (connectionState != 2) // not-connected + return; + connectionState = 3; // disconnecting + + if (!inError && tid != 0) { + try { + send( new SmbComTreeDisconnect(), null ); + } catch( SmbException se ) { + if (session.transport.log.level > 1) { + se.printStackTrace( session.transport.log ); + } + } + } + inDfs = false; + inDomainDfs = false; + + connectionState = 0; + + session.transport.notifyAll(); +} + } + + public String toString() { + return "SmbTree[share=" + share + + ",service=" + service + + ",tid=" + tid + + ",inDfs=" + inDfs + + ",inDomainDfs=" + inDomainDfs + + ",connectionState=" + connectionState + "]"; + } +} diff --git a/src/jcifs/smb/TestLocking.java b/src/jcifs/smb/TestLocking.java new file mode 100644 index 0000000..44e0414 --- /dev/null +++ b/src/jcifs/smb/TestLocking.java @@ -0,0 +1,124 @@ +package jcifs.smb; + +import java.io.InputStream; +import java.io.IOException; + +public class TestLocking implements Runnable +{ + + int numThreads = 1; + int numIter = 1; + long delay = 100; + String url = null; + int numComplete = 0; + long ltime = 0L; + + public void run() + { + try { + SmbFile f = new SmbFile(url); + SmbFile d = new SmbFile(f.getParent()); + byte[] buf = new byte[1024]; + + for (int ii = 0; ii < numIter; ii++) { + + synchronized (this) { + ltime = System.currentTimeMillis(); + wait(); + } + + try { + double r = Math.random(); + if (r < 0.333) { + f.exists(); +// System.out.print('e'); + } else if (r < 0.667) { + d.listFiles(); +// System.out.print('l'); + } else if (r < 1.0) { + InputStream in = f.getInputStream(); + while (in.read(buf) > 0) { +// System.out.print('r'); + } + in.close(); + } + } catch (IOException ioe) { + System.err.println(ioe.getMessage()); +//ioe.printStackTrace(System.err); + } + + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + numComplete++; + } + } + + public static void main(String[] args) throws Exception + { + if (args.length < 1) { + System.err.println("usage: TestLocking [-t ] [-i ] [-d ] url"); + System.exit(1); + } + + TestLocking t = new TestLocking(); + t.ltime = System.currentTimeMillis(); + + for (int ai = 0; ai < args.length; ai++) { + if (args[ai].equals("-t")) { + ai++; + t.numThreads = Integer.parseInt(args[ai]); + } else if (args[ai].equals("-i")) { + ai++; + t.numIter = Integer.parseInt(args[ai]); + } else if (args[ai].equals("-d")) { + ai++; + t.delay = Long.parseLong(args[ai]); + } else { + t.url = args[ai]; + } + } + + Thread[] threads = new Thread[t.numThreads]; + int ti; + + for (ti = 0; ti < t.numThreads; ti++) { + threads[ti] = new Thread(t); + System.out.print(threads[ti].getName()); + threads[ti].start(); + } + + while (t.numComplete < t.numThreads) { + long delay; + + do { + delay = 2L; + + synchronized (t) { + long expire = t.ltime + t.delay; + long ctime = System.currentTimeMillis(); + + if (expire > ctime) + delay = expire - ctime; + } + +if (delay > 2) +System.out.println("delay=" + delay); + Thread.sleep(delay); + } while (delay > 2); + + synchronized (t) { + t.notifyAll(); + } +//System.out.println("numComplete=" + t.numComplete + ",numThreads=" + t.numThreads); + } + + for (ti = 0; ti < t.numThreads; ti++) { + threads[ti].join(); + System.out.print(threads[ti].getName()); + } + + System.out.println(); + } +} diff --git a/src/jcifs/smb/Trans2FindFirst2.java b/src/jcifs/smb/Trans2FindFirst2.java new file mode 100644 index 0000000..7cff9ff --- /dev/null +++ b/src/jcifs/smb/Trans2FindFirst2.java @@ -0,0 +1,119 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.Config; +import jcifs.util.Hexdump; + +class Trans2FindFirst2 extends SmbComTransaction { + + // flags + + private static final int FLAGS_CLOSE_AFTER_THIS_REQUEST = 0x01; + private static final int FLAGS_CLOSE_IF_END_REACHED = 0x02; + private static final int FLAGS_RETURN_RESUME_KEYS = 0x04; + private static final int FLAGS_RESUME_FROM_PREVIOUS_END = 0x08; + private static final int FLAGS_FIND_WITH_BACKUP_INTENT = 0x10; + + private static final int DEFAULT_LIST_SIZE = 65535; + private static final int DEFAULT_LIST_COUNT = 200; + + private int searchAttributes; + private int flags; + private int informationLevel; + private int searchStorageType = 0; + private String wildcard; + + // information levels + + static final int SMB_INFO_STANDARD = 1; + static final int SMB_INFO_QUERY_EA_SIZE = 2; + static final int SMB_INFO_QUERY_EAS_FROM_LIST = 3; + static final int SMB_FIND_FILE_DIRECTORY_INFO = 0x101; + static final int SMB_FIND_FILE_FULL_DIRECTORY_INFO = 0x102; + static final int SMB_FILE_NAMES_INFO = 0x103; + static final int SMB_FILE_BOTH_DIRECTORY_INFO = 0x104; + + static final int LIST_SIZE = Config.getInt( "jcifs.smb.client.listSize", DEFAULT_LIST_SIZE ); + static final int LIST_COUNT = Config.getInt( "jcifs.smb.client.listCount", DEFAULT_LIST_COUNT ); + + Trans2FindFirst2( String filename, String wildcard, int searchAttributes ) { + if( filename.equals( "\\" )) { + this.path = filename; + } else { + this.path = filename + "\\"; + } + this.wildcard = wildcard; + this.searchAttributes = searchAttributes & 0x37; /* generally ignored tho */ + command = SMB_COM_TRANSACTION2; + subCommand = TRANS2_FIND_FIRST2; + + flags = 0x00; + informationLevel = SMB_FILE_BOTH_DIRECTORY_INFO; + + totalDataCount = 0; + maxParameterCount = 10; + maxDataCount = LIST_SIZE; + maxSetupCount = 0; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + return 2; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( searchAttributes, dst, dstIndex ); + dstIndex += 2; + writeInt2( LIST_COUNT, dst, dstIndex ); + dstIndex += 2; + writeInt2( flags, dst, dstIndex ); + dstIndex += 2; + writeInt2( informationLevel, dst, dstIndex ); + dstIndex += 2; + writeInt4( searchStorageType, dst, dstIndex ); + dstIndex += 4; + dstIndex += writeString( path + wildcard, dst, dstIndex ); + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "Trans2FindFirst2[" + super.toString() + + ",searchAttributes=0x" + Hexdump.toHexString( searchAttributes, 2 ) + + ",searchCount=" + LIST_COUNT + + ",flags=0x" + Hexdump.toHexString( flags, 2 ) + + ",informationLevel=0x" + Hexdump.toHexString( informationLevel, 3 ) + + ",searchStorageType=" + searchStorageType + + ",filename=" + path + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2FindFirst2Response.java b/src/jcifs/smb/Trans2FindFirst2Response.java new file mode 100644 index 0000000..24da040 --- /dev/null +++ b/src/jcifs/smb/Trans2FindFirst2Response.java @@ -0,0 +1,233 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.UnsupportedEncodingException; +import java.util.Date; + +class Trans2FindFirst2Response extends SmbComTransactionResponse { + + // information levels + + static final int SMB_INFO_STANDARD = 1; + static final int SMB_INFO_QUERY_EA_SIZE = 2; + static final int SMB_INFO_QUERY_EAS_FROM_LIST = 3; + static final int SMB_FIND_FILE_DIRECTORY_INFO = 0x101; + static final int SMB_FIND_FILE_FULL_DIRECTORY_INFO = 0x102; + static final int SMB_FILE_NAMES_INFO = 0x103; + static final int SMB_FILE_BOTH_DIRECTORY_INFO = 0x104; + + class SmbFindFileBothDirectoryInfo implements FileEntry { + int nextEntryOffset; + int fileIndex; + long creationTime; + long lastAccessTime; + long lastWriteTime; + long changeTime; + long endOfFile; + long allocationSize; + int extFileAttributes; + int fileNameLength; + int eaSize; + int shortNameLength; + String shortName; + String filename; + + public String getName() { + return filename; + } + public int getType() { + return SmbFile.TYPE_FILESYSTEM; + } + public int getAttributes() { + return extFileAttributes; + } + public long createTime() { + return creationTime; + } + public long lastModified() { + return lastWriteTime; + } + public long length() { + return endOfFile; + } + + public String toString() { + return new String( "SmbFindFileBothDirectoryInfo[" + + "nextEntryOffset=" + nextEntryOffset + + ",fileIndex=" + fileIndex + + ",creationTime=" + new Date( creationTime ) + + ",lastAccessTime=" + new Date( lastAccessTime ) + + ",lastWriteTime=" + new Date( lastWriteTime ) + + ",changeTime=" + new Date( changeTime ) + + ",endOfFile=" + endOfFile + + ",allocationSize=" + allocationSize + + ",extFileAttributes=" + extFileAttributes + + ",fileNameLength=" + fileNameLength + + ",eaSize=" + eaSize + + ",shortNameLength=" + shortNameLength + + ",shortName=" + shortName + + ",filename=" + filename + "]" ); + } + } + + int sid; + boolean isEndOfSearch; + int eaErrorOffset; + int lastNameOffset, lastNameBufferIndex; + String lastName; + int resumeKey; + + + Trans2FindFirst2Response() { + command = SMB_COM_TRANSACTION2; + subCommand = SmbComTransaction.TRANS2_FIND_FIRST2; + } + + String readString( byte[] src, int srcIndex, int len ) { + String str = null; + try { + if( useUnicode ) { + // should Unicode alignment be corrected for here? + str = new String( src, srcIndex, len, UNI_ENCODING ); + } else { + + /* On NT without Unicode the fileNameLength + * includes the '\0' whereas on win98 it doesn't. I + * guess most clients only support non-unicode so + * they don't run into this. + */ + + /* UPDATE: Maybe not! Could this be a Unicode alignment issue. I hope + * so. We cannot just comment out this method and use readString of + * ServerMessageBlock.java because the arguments are different, however + * one might be able to reduce this. + */ + + if( len > 0 && src[srcIndex + len - 1] == '\0' ) { + len--; + } + str = new String( src, srcIndex, len, ServerMessageBlock.OEM_ENCODING ); + } + } catch( UnsupportedEncodingException uee ) { + if( log.level > 1 ) + uee.printStackTrace( log ); + } + return str; + } + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + + if( subCommand == SmbComTransaction.TRANS2_FIND_FIRST2 ) { + sid = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + } + numEntries = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + isEndOfSearch = ( buffer[bufferIndex] & 0x01 ) == 0x01 ? true : false; + bufferIndex += 2; + eaErrorOffset = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + lastNameOffset = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + + return bufferIndex - start; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + SmbFindFileBothDirectoryInfo e; + + lastNameBufferIndex = bufferIndex + lastNameOffset; + + results = new SmbFindFileBothDirectoryInfo[numEntries]; + for( int i = 0; i < numEntries; i++ ) { + results[i] = e = new SmbFindFileBothDirectoryInfo(); + + e.nextEntryOffset = readInt4( buffer, bufferIndex ); + e.fileIndex = readInt4( buffer, bufferIndex + 4 ); + e.creationTime = readTime( buffer, bufferIndex + 8 ); + // e.lastAccessTime = readTime( buffer, bufferIndex + 16 ); + e.lastWriteTime = readTime( buffer, bufferIndex + 24 ); + // e.changeTime = readTime( buffer, bufferIndex + 32 ); + e.endOfFile = readInt8( buffer, bufferIndex + 40 ); + // e.allocationSize = readInt8( buffer, bufferIndex + 48 ); + e.extFileAttributes = readInt4( buffer, bufferIndex + 56 ); + e.fileNameLength = readInt4( buffer, bufferIndex + 60 ); + // e.eaSize = readInt4( buffer, bufferIndex + 64 ); + // e.shortNameLength = buffer[bufferIndex + 68] & 0xFF; + + /* With NT, the shortName is in Unicode regardless of what is negotiated. + */ + + // e.shortName = readString( buffer, bufferIndex + 70, e.shortNameLength ); + e.filename = readString( buffer, bufferIndex + 94, e.fileNameLength ); + + /* lastNameOffset ends up pointing to either to + * the exact location of the filename(e.g. Win98) + * or to the start of the entry containing the + * filename(e.g. NT). Ahhrg! In either case the + * lastNameOffset falls between the start of the + * entry and the next entry. + */ + + if( lastNameBufferIndex >= bufferIndex && ( e.nextEntryOffset == 0 || + lastNameBufferIndex < ( bufferIndex + e.nextEntryOffset ))) { + lastName = e.filename; + resumeKey = e.fileIndex; + } + + bufferIndex += e.nextEntryOffset; + } + + /* last nextEntryOffset for NT 4(but not 98) is 0 so we must + * use dataCount or our accounting will report an error for NT :~( + */ + + //return bufferIndex - start; + + return dataCount; + } + public String toString() { + String c; + if( subCommand == SmbComTransaction.TRANS2_FIND_FIRST2 ) { + c = "Trans2FindFirst2Response["; + } else { + c = "Trans2FindNext2Response["; + } + return new String( c + super.toString() + + ",sid=" + sid + + ",searchCount=" + numEntries + + ",isEndOfSearch=" + isEndOfSearch + + ",eaErrorOffset=" + eaErrorOffset + + ",lastNameOffset=" + lastNameOffset + + ",lastName=" + lastName + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2FindNext2.java b/src/jcifs/smb/Trans2FindNext2.java new file mode 100644 index 0000000..365580a --- /dev/null +++ b/src/jcifs/smb/Trans2FindNext2.java @@ -0,0 +1,92 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.Config; +import jcifs.util.Hexdump; + +class Trans2FindNext2 extends SmbComTransaction { + + private int sid, informationLevel, resumeKey, flags; + private String filename; + + Trans2FindNext2( int sid, int resumeKey, String filename ) { + this.sid = sid; + this.resumeKey = resumeKey; + this.filename = filename; + command = SMB_COM_TRANSACTION2; + subCommand = TRANS2_FIND_NEXT2; + informationLevel = Trans2FindFirst2.SMB_FILE_BOTH_DIRECTORY_INFO; + flags = 0x00; + maxParameterCount = 8; + maxDataCount = Trans2FindFirst2.LIST_SIZE; + maxSetupCount = 0; + } + + void reset( int resumeKey, String lastName ) { + super.reset(); + this.resumeKey = resumeKey; + this.filename = lastName; + flags2 = 0; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + return 2; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( sid, dst, dstIndex ); + dstIndex += 2; + writeInt2( Trans2FindFirst2.LIST_COUNT, dst, dstIndex ); + dstIndex += 2; + writeInt2( informationLevel, dst, dstIndex ); + dstIndex += 2; + writeInt4( resumeKey, dst, dstIndex ); + dstIndex += 4; + writeInt2( flags, dst, dstIndex ); + dstIndex += 2; + dstIndex += writeString( filename, dst, dstIndex ); + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "Trans2FindNext2[" + super.toString() + + ",sid=" + sid + + ",searchCount=" + Trans2FindFirst2.LIST_SIZE + + ",informationLevel=0x" + Hexdump.toHexString( informationLevel, 3 ) + + ",resumeKey=0x" + Hexdump.toHexString( resumeKey, 4 ) + + ",flags=0x" + Hexdump.toHexString( flags, 2 ) + + ",filename=" + filename + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2GetDfsReferral.java b/src/jcifs/smb/Trans2GetDfsReferral.java new file mode 100644 index 0000000..a64b2f8 --- /dev/null +++ b/src/jcifs/smb/Trans2GetDfsReferral.java @@ -0,0 +1,66 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class Trans2GetDfsReferral extends SmbComTransaction { + + private int maxReferralLevel = 3; + + Trans2GetDfsReferral( String filename ) { + path = filename; + command = SMB_COM_TRANSACTION2; + subCommand = TRANS2_GET_DFS_REFERRAL; + totalDataCount = 0; + maxParameterCount = 0; + maxDataCount = 4096; + maxSetupCount = (byte)0x00; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + return 2; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( maxReferralLevel, dst, dstIndex ); + dstIndex += 2; + dstIndex += writeString( path, dst, dstIndex ); + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "Trans2GetDfsReferral[" + super.toString() + + ",maxReferralLevel=0x" + maxReferralLevel + + ",filename=" + path + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2GetDfsReferralResponse.java b/src/jcifs/smb/Trans2GetDfsReferralResponse.java new file mode 100644 index 0000000..0c51b7d --- /dev/null +++ b/src/jcifs/smb/Trans2GetDfsReferralResponse.java @@ -0,0 +1,141 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Date; + +class Trans2GetDfsReferralResponse extends SmbComTransactionResponse { + + class Referral { + private int version; + private int size; + private int serverType; + private int flags; + private int proximity; + private int pathOffset; + private int altPathOffset; + private int nodeOffset; + private String altPath; + + int ttl; + String path = null; + String node = null; + + int readWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + + version = readInt2( buffer, bufferIndex ); +if( version != 3 && version != 1 ) { + throw new RuntimeException( "Version " + version + " referral not supported. Please report this to jcifs at samba dot org." ); +} + bufferIndex += 2; + size = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + serverType = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + flags = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + if( version == 3 ) { + proximity = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + ttl = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + pathOffset = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + altPathOffset = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + nodeOffset = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + + path = readString( buffer, start + pathOffset, len, (flags2 & FLAGS2_UNICODE) != 0); + if (nodeOffset > 0) + node = readString( buffer, start + nodeOffset, len, (flags2 & FLAGS2_UNICODE) != 0); + } else if( version == 1 ) { + node = readString( buffer, bufferIndex, len, (flags2 & FLAGS2_UNICODE) != 0); + } + + return size; + } + + public String toString() { + return new String( "Referral[" + + "version=" + version + ",size=" + size + + ",serverType=" + serverType + ",flags=" + flags + + ",proximity=" + proximity + ",ttl=" + ttl + + ",pathOffset=" + pathOffset + ",altPathOffset=" + altPathOffset + + ",nodeOffset=" + nodeOffset + ",path=" + path + ",altPath=" + altPath + + ",node=" + node + "]" ); + } + } + + int pathConsumed; + int numReferrals; + int flags; + Referral[] referrals; + + Trans2GetDfsReferralResponse() { + subCommand = SmbComTransaction.TRANS2_GET_DFS_REFERRAL; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + int start = bufferIndex; + + pathConsumed = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + /* Samba 2.2.8a will reply with Unicode paths even though + * ASCII is negotiated so we must use flags2 (probably + * should anyway). + */ + if((flags2 & FLAGS2_UNICODE) != 0) { + pathConsumed /= 2; + } + numReferrals = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + flags = readInt2( buffer, bufferIndex ); + bufferIndex += 4; + + referrals = new Referral[numReferrals]; + for (int ri = 0; ri < numReferrals; ri++) { + referrals[ri] = new Referral(); + bufferIndex += referrals[ri].readWireFormat( buffer, bufferIndex, len ); + } + + return bufferIndex - start; + } + public String toString() { + return new String( "Trans2GetDfsReferralResponse[" + + super.toString() + ",pathConsumed=" + pathConsumed + + ",numReferrals=" + numReferrals + ",flags=" + flags + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2QueryFSInformation.java b/src/jcifs/smb/Trans2QueryFSInformation.java new file mode 100644 index 0000000..a2e6bb3 --- /dev/null +++ b/src/jcifs/smb/Trans2QueryFSInformation.java @@ -0,0 +1,74 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.util.Hexdump; + +class Trans2QueryFSInformation extends SmbComTransaction { + + private int informationLevel; + + Trans2QueryFSInformation( int informationLevel ) { + command = SMB_COM_TRANSACTION2; + subCommand = TRANS2_QUERY_FS_INFORMATION; + this.informationLevel = informationLevel; + totalParameterCount = 2; + totalDataCount = 0; + maxParameterCount = 0; + maxDataCount = 800; + maxSetupCount = 0; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + return 2; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( informationLevel, dst, dstIndex ); + dstIndex += 2; + + /* windows98 has what appears to be another 4 0's followed by the share + * name as a zero terminated ascii string "\TMP" + '\0' + * + * As is this works, but it deviates from the spec section 4.1.6.6 but + * maybe I should put it in. Wonder what NT does? + */ + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "Trans2QueryFSInformation[" + super.toString() + + ",informationLevel=0x" + Hexdump.toHexString( informationLevel, 3 ) + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2QueryFSInformationResponse.java b/src/jcifs/smb/Trans2QueryFSInformationResponse.java new file mode 100644 index 0000000..6a5fe66 --- /dev/null +++ b/src/jcifs/smb/Trans2QueryFSInformationResponse.java @@ -0,0 +1,164 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.UnsupportedEncodingException; + +class Trans2QueryFSInformationResponse extends SmbComTransactionResponse { + + // information levels + static final int SMB_INFO_ALLOCATION = 1; + static final int SMB_QUERY_FS_SIZE_INFO = 0x103; + static final int SMB_FS_FULL_SIZE_INFORMATION = 1007; + + class SmbInfoAllocation implements AllocInfo { + long alloc; // Also handles SmbQueryFSSizeInfo + long free; + int sectPerAlloc; + int bytesPerSect; + + public long getCapacity() { + return alloc * sectPerAlloc * bytesPerSect; + } + public long getFree() { + return free * sectPerAlloc * bytesPerSect; + } + public String toString() { + return new String( "SmbInfoAllocation[" + + "alloc=" + alloc + ",free=" + free + + ",sectPerAlloc=" + sectPerAlloc + + ",bytesPerSect=" + bytesPerSect + "]" ); + } + } + + private int informationLevel; + + AllocInfo info; + + Trans2QueryFSInformationResponse( int informationLevel ) { + this.informationLevel = informationLevel; + command = SMB_COM_TRANSACTION2; + subCommand = SmbComTransaction.TRANS2_QUERY_FS_INFORMATION; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + switch( informationLevel ) { + case SMB_INFO_ALLOCATION: + return readSmbInfoAllocationWireFormat( buffer, bufferIndex ); + case SMB_QUERY_FS_SIZE_INFO: + return readSmbQueryFSSizeInfoWireFormat( buffer, bufferIndex ); + case SMB_FS_FULL_SIZE_INFORMATION: + return readFsFullSizeInformationWireFormat( buffer, bufferIndex ); + default: + return 0; + } + } + + int readSmbInfoAllocationWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + SmbInfoAllocation info = new SmbInfoAllocation(); + + bufferIndex += 4; // skip idFileSystem + + info.sectPerAlloc = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + + info.alloc = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + + info.free = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + + info.bytesPerSect = readInt2( buffer, bufferIndex ); + bufferIndex += 4; + + this.info = info; + + return bufferIndex - start; + } + int readSmbQueryFSSizeInfoWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + SmbInfoAllocation info = new SmbInfoAllocation(); + + info.alloc = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + + info.free = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + + info.sectPerAlloc = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + + info.bytesPerSect = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + + this.info = info; + + return bufferIndex - start; + } + int readFsFullSizeInformationWireFormat( byte[] buffer, int bufferIndex ) + { + int start = bufferIndex; + + SmbInfoAllocation info = new SmbInfoAllocation(); + + // Read total allocation units. + info.alloc = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + + // read caller available allocation units + info.free = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + + // skip actual free units + bufferIndex += 8; + + info.sectPerAlloc = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + + info.bytesPerSect = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + + this.info = info; + + return bufferIndex - start; + } + + public String toString() { + return new String( "Trans2QueryFSInformationResponse[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2QueryPathInformation.java b/src/jcifs/smb/Trans2QueryPathInformation.java new file mode 100644 index 0000000..ba42c50 --- /dev/null +++ b/src/jcifs/smb/Trans2QueryPathInformation.java @@ -0,0 +1,73 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import jcifs.util.Hexdump; + +class Trans2QueryPathInformation extends SmbComTransaction { + + private int informationLevel; + + Trans2QueryPathInformation( String filename, int informationLevel ) { + path = filename; + this.informationLevel = informationLevel; + command = SMB_COM_TRANSACTION2; + subCommand = TRANS2_QUERY_PATH_INFORMATION; + totalDataCount = 0; + maxParameterCount = 2; + maxDataCount = 40; + maxSetupCount = (byte)0x00; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + return 2; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( informationLevel, dst, dstIndex ); + dstIndex += 2; + dst[dstIndex++] = (byte)0x00; + dst[dstIndex++] = (byte)0x00; + dst[dstIndex++] = (byte)0x00; + dst[dstIndex++] = (byte)0x00; + dstIndex += writeString( path, dst, dstIndex ); + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "Trans2QueryPathInformation[" + super.toString() + + ",informationLevel=0x" + Hexdump.toHexString( informationLevel, 3 ) + + ",filename=" + path + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2QueryPathInformationResponse.java b/src/jcifs/smb/Trans2QueryPathInformationResponse.java new file mode 100644 index 0000000..38ba37c --- /dev/null +++ b/src/jcifs/smb/Trans2QueryPathInformationResponse.java @@ -0,0 +1,160 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.util.Date; +import jcifs.util.Hexdump; + +class Trans2QueryPathInformationResponse extends SmbComTransactionResponse { + + // information levels + static final int SMB_QUERY_FILE_BASIC_INFO = 0x101; + static final int SMB_QUERY_FILE_STANDARD_INFO = 0x102; + + class SmbQueryFileBasicInfo implements Info { + long createTime; + long lastAccessTime; + long lastWriteTime; + long changeTime; + int attributes; + + public int getAttributes() { + return attributes; + } + public long getCreateTime() { + return createTime; + } + public long getLastWriteTime() { + return lastWriteTime; + } + public long getSize() { + return 0L; + } + public String toString() { + return new String( "SmbQueryFileBasicInfo[" + + "createTime=" + new Date( createTime ) + + ",lastAccessTime=" + new Date( lastAccessTime ) + + ",lastWriteTime=" + new Date( lastWriteTime ) + + ",changeTime=" + new Date( changeTime ) + + ",attributes=0x" + Hexdump.toHexString( attributes, 4 ) + "]" ); + } + } + class SmbQueryFileStandardInfo implements Info { + long allocationSize; + long endOfFile; + int numberOfLinks; + boolean deletePending; + boolean directory; + + public int getAttributes() { + return 0; + } + public long getCreateTime() { + return 0L; + } + public long getLastWriteTime() { + return 0L; + } + public long getSize() { + return endOfFile; + } + public String toString() { + return new String( "SmbQueryInfoStandard[" + + "allocationSize=" + allocationSize + + ",endOfFile=" + endOfFile + + ",numberOfLinks=" + numberOfLinks + + ",deletePending=" + deletePending + + ",directory=" + directory + "]" ); + } + } + + private int informationLevel; + + Info info; + + Trans2QueryPathInformationResponse( int informationLevel ) { + this.informationLevel = informationLevel; + subCommand = SmbComTransaction.TRANS2_QUERY_PATH_INFORMATION; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + // observed two zero bytes here with at least win98 + return 2; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + switch( informationLevel ) { + case SMB_QUERY_FILE_BASIC_INFO: + return readSmbQueryFileBasicInfoWireFormat( buffer, bufferIndex ); + case SMB_QUERY_FILE_STANDARD_INFO: + return readSmbQueryFileStandardInfoWireFormat( buffer, bufferIndex ); + default: + return 0; + } + } + int readSmbQueryFileStandardInfoWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + SmbQueryFileStandardInfo info = new SmbQueryFileStandardInfo(); + info.allocationSize = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + info.endOfFile = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + info.numberOfLinks = readInt4( buffer, bufferIndex ); + bufferIndex += 4; + info.deletePending = ( buffer[bufferIndex++] & 0xFF ) > 0; + info.directory = ( buffer[bufferIndex++] & 0xFF ) > 0; + this.info = info; + + return bufferIndex - start; + } + int readSmbQueryFileBasicInfoWireFormat( byte[] buffer, int bufferIndex ) { + int start = bufferIndex; + + SmbQueryFileBasicInfo info = new SmbQueryFileBasicInfo(); + info.createTime = readTime( buffer, bufferIndex ); + bufferIndex += 8; + info.lastAccessTime = readTime( buffer, bufferIndex ); + bufferIndex += 8; + info.lastWriteTime = readTime( buffer, bufferIndex ); + bufferIndex += 8; + info.changeTime = readTime( buffer, bufferIndex ); + bufferIndex += 8; + info.attributes = readInt2( buffer, bufferIndex ); + bufferIndex += 2; + this.info = info; + + return bufferIndex - start; + } + public String toString() { + return new String( "Trans2QueryPathInformationResponse[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2SetFileInformation.java b/src/jcifs/smb/Trans2SetFileInformation.java new file mode 100644 index 0000000..546904e --- /dev/null +++ b/src/jcifs/smb/Trans2SetFileInformation.java @@ -0,0 +1,89 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class Trans2SetFileInformation extends SmbComTransaction { + + static final int SMB_FILE_BASIC_INFO = 0x101; + + private int fid; + private int attributes; + private long createTime, lastWriteTime; + + Trans2SetFileInformation( int fid, int attributes, long createTime, long lastWriteTime ) { + this.fid = fid; + this.attributes = attributes; + this.createTime = createTime; + this.lastWriteTime = lastWriteTime; + command = SMB_COM_TRANSACTION2; + subCommand = TRANS2_SET_FILE_INFORMATION; + maxParameterCount = 6; + maxDataCount = 0; + maxSetupCount = (byte)0x00; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + return 2; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeInt2( fid, dst, dstIndex ); + dstIndex += 2; + writeInt2( SMB_FILE_BASIC_INFO, dst, dstIndex ); + dstIndex += 2; + writeInt2( 0, dst, dstIndex ); + dstIndex += 2; + + return dstIndex - start; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + int start = dstIndex; + + writeTime( createTime, dst, dstIndex ); dstIndex += 8; + writeInt8( 0L, dst, dstIndex ); dstIndex += 8; + writeTime( lastWriteTime, dst, dstIndex ); dstIndex += 8; + writeInt8( 0L, dst, dstIndex ); dstIndex += 8; +/* Samba 2.2.7 needs ATTR_NORMAL + */ + writeInt2( 0x80 | attributes, dst, dstIndex ); dstIndex += 2; + /* 6 zeros observed with NT */ + writeInt8( 0L, dst, dstIndex ); dstIndex += 6; + + /* Also observed 4 byte alignment but we stick + * with the default for jCIFS which is 2 */ + + return dstIndex - start; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "Trans2SetFileInformation[" + super.toString() + + ",fid=" + fid + "]" ); + } +} diff --git a/src/jcifs/smb/Trans2SetFileInformationResponse.java b/src/jcifs/smb/Trans2SetFileInformationResponse.java new file mode 100644 index 0000000..ee084d5 --- /dev/null +++ b/src/jcifs/smb/Trans2SetFileInformationResponse.java @@ -0,0 +1,49 @@ +/* jcifs smb client library in Java + * Copyright (C) 2003 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class Trans2SetFileInformationResponse extends SmbComTransactionResponse { + + Trans2SetFileInformationResponse() { + subCommand = SmbComTransaction.TRANS2_SET_FILE_INFORMATION; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "Trans2SetFileInformationResponse[" + + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/TransCallNamedPipe.java b/src/jcifs/smb/TransCallNamedPipe.java new file mode 100644 index 0000000..ad9c4d7 --- /dev/null +++ b/src/jcifs/smb/TransCallNamedPipe.java @@ -0,0 +1,73 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class TransCallNamedPipe extends SmbComTransaction { + + private byte[] pipeData; + private int pipeDataOff, pipeDataLen; + + TransCallNamedPipe( String pipeName, byte[] data, int off, int len ) { + name = pipeName; + pipeData = data; + pipeDataOff = off; + pipeDataLen = len; + command = SMB_COM_TRANSACTION; + subCommand = TRANS_CALL_NAMED_PIPE; + timeout = 0xFFFFFFFF; + maxParameterCount = 0; + maxDataCount = 0xFFFF; + maxSetupCount = (byte)0x00; + setupCount = 2; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + // this says "Transaction priority" in netmon + dst[dstIndex++] = (byte)0x00; // no FID + dst[dstIndex++] = (byte)0x00; + return 4; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + if(( dst.length - dstIndex ) < pipeDataLen ) { + if( log.level >= 3 ) + log.println( "TransCallNamedPipe data too long for buffer" ); + return 0; + } + System.arraycopy( pipeData, pipeDataOff, dst, dstIndex, pipeDataLen ); + return pipeDataLen; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "TransCallNamedPipe[" + super.toString() + + ",pipeName=" + name + "]" ); + } +} diff --git a/src/jcifs/smb/TransCallNamedPipeResponse.java b/src/jcifs/smb/TransCallNamedPipeResponse.java new file mode 100644 index 0000000..7b20b47 --- /dev/null +++ b/src/jcifs/smb/TransCallNamedPipeResponse.java @@ -0,0 +1,57 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class TransCallNamedPipeResponse extends SmbComTransactionResponse { + + private SmbNamedPipe pipe; + + TransCallNamedPipeResponse( SmbNamedPipe pipe ) { + this.pipe = pipe; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + if( pipe.pipeIn != null ) { + TransactNamedPipeInputStream in = (TransactNamedPipeInputStream)pipe.pipeIn; + synchronized( in.lock ) { + in.receive( buffer, bufferIndex, len ); + in.lock.notify(); + } + } + return len; + } + public String toString() { + return new String( "TransCallNamedPipeResponse[" + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/TransPeekNamedPipe.java b/src/jcifs/smb/TransPeekNamedPipe.java new file mode 100644 index 0000000..de2a252 --- /dev/null +++ b/src/jcifs/smb/TransPeekNamedPipe.java @@ -0,0 +1,63 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class TransPeekNamedPipe extends SmbComTransaction { + + private int fid; + + TransPeekNamedPipe( String pipeName, int fid ) { + name = pipeName; + this.fid = fid; + command = SMB_COM_TRANSACTION; + subCommand = TRANS_PEEK_NAMED_PIPE; + timeout = 0xFFFFFFFF; + maxParameterCount = 6; + maxDataCount = 1; + maxSetupCount = (byte)0x00; + setupCount = 2; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + // this says "Transaction priority" in netmon + writeInt2( fid, dst, dstIndex ); + return 4; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "TransPeekNamedPipe[" + super.toString() + + ",pipeName=" + name + "]" ); + } +} diff --git a/src/jcifs/smb/TransPeekNamedPipeResponse.java b/src/jcifs/smb/TransPeekNamedPipeResponse.java new file mode 100644 index 0000000..819512c --- /dev/null +++ b/src/jcifs/smb/TransPeekNamedPipeResponse.java @@ -0,0 +1,61 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class TransPeekNamedPipeResponse extends SmbComTransactionResponse { + + private SmbNamedPipe pipe; + private int head; + + static final int STATUS_DISCONNECTED = 1; + static final int STATUS_LISTENING = 2; + static final int STATUS_CONNECTION_OK = 3; + static final int STATUS_SERVER_END_CLOSED = 4; + + int status, available; + + TransPeekNamedPipeResponse( SmbNamedPipe pipe ) { + this.pipe = pipe; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + available = readInt2( buffer, bufferIndex ); bufferIndex += 2; + head = readInt2( buffer, bufferIndex ); bufferIndex += 2; + status = readInt2( buffer, bufferIndex ); + return 6; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "TransPeekNamedPipeResponse[" + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/TransTransactNamedPipe.java b/src/jcifs/smb/TransTransactNamedPipe.java new file mode 100644 index 0000000..ba0fe4d --- /dev/null +++ b/src/jcifs/smb/TransTransactNamedPipe.java @@ -0,0 +1,72 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class TransTransactNamedPipe extends SmbComTransaction { + + private byte[] pipeData; + private int pipeFid, pipeDataOff, pipeDataLen; + + TransTransactNamedPipe( int fid, byte[] data, int off, int len ) { + pipeFid = fid; + pipeData = data; + pipeDataOff = off; + pipeDataLen = len; + command = SMB_COM_TRANSACTION; + subCommand = TRANS_TRANSACT_NAMED_PIPE; + maxParameterCount = 0; + maxDataCount = 0xFFFF; + maxSetupCount = (byte)0x00; + setupCount = 2; + name = "\\PIPE\\"; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + writeInt2( pipeFid, dst, dstIndex ); + dstIndex += 2; + return 4; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + if(( dst.length - dstIndex ) < pipeDataLen ) { + if( log.level >= 3 ) + log.println( "TransTransactNamedPipe data too long for buffer" ); + return 0; + } + System.arraycopy( pipeData, pipeDataOff, dst, dstIndex, pipeDataLen ); + return pipeDataLen; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "TransTransactNamedPipe[" + super.toString() + + ",pipeFid=" + pipeFid + "]" ); + } +} diff --git a/src/jcifs/smb/TransTransactNamedPipeResponse.java b/src/jcifs/smb/TransTransactNamedPipeResponse.java new file mode 100644 index 0000000..7f99a79 --- /dev/null +++ b/src/jcifs/smb/TransTransactNamedPipeResponse.java @@ -0,0 +1,57 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class TransTransactNamedPipeResponse extends SmbComTransactionResponse { + + private SmbNamedPipe pipe; + + TransTransactNamedPipeResponse( SmbNamedPipe pipe ) { + this.pipe = pipe; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + if( pipe.pipeIn != null ) { + TransactNamedPipeInputStream in = (TransactNamedPipeInputStream)pipe.pipeIn; + synchronized( in.lock ) { + in.receive( buffer, bufferIndex, len ); + in.lock.notify(); + } + } + return len; + } + public String toString() { + return new String( "TransTransactNamedPipeResponse[" + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/TransWaitNamedPipe.java b/src/jcifs/smb/TransWaitNamedPipe.java new file mode 100644 index 0000000..ee71ad4 --- /dev/null +++ b/src/jcifs/smb/TransWaitNamedPipe.java @@ -0,0 +1,60 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class TransWaitNamedPipe extends SmbComTransaction { + + TransWaitNamedPipe( String pipeName ) { + name = pipeName; + command = SMB_COM_TRANSACTION; + subCommand = TRANS_WAIT_NAMED_PIPE; + timeout = 0xFFFFFFFF; + maxParameterCount = 0; + maxDataCount = 0; + maxSetupCount = (byte)0x00; + setupCount = 2; + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + dst[dstIndex++] = subCommand; + dst[dstIndex++] = (byte)0x00; + dst[dstIndex++] = (byte)0x00; // no FID + dst[dstIndex++] = (byte)0x00; + return 4; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "TransWaitNamedPipe[" + super.toString() + + ",pipeName=" + name + "]" ); + } +} diff --git a/src/jcifs/smb/TransWaitNamedPipeResponse.java b/src/jcifs/smb/TransWaitNamedPipeResponse.java new file mode 100644 index 0000000..5d52b75 --- /dev/null +++ b/src/jcifs/smb/TransWaitNamedPipeResponse.java @@ -0,0 +1,49 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +class TransWaitNamedPipeResponse extends SmbComTransactionResponse { + + // not much to this one is there :~) + + TransWaitNamedPipeResponse() { + } + + int writeSetupWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeParametersWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int writeDataWireFormat( byte[] dst, int dstIndex ) { + return 0; + } + int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) { + return 0; + } + public String toString() { + return new String( "TransWaitNamedPipeResponse[" + super.toString() + "]" ); + } +} diff --git a/src/jcifs/smb/TransactNamedPipeInputStream.java b/src/jcifs/smb/TransactNamedPipeInputStream.java new file mode 100644 index 0000000..b779690 --- /dev/null +++ b/src/jcifs/smb/TransactNamedPipeInputStream.java @@ -0,0 +1,136 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.InputStream; +import java.io.IOException; +import java.net.UnknownHostException; +import java.net.MalformedURLException; + +class TransactNamedPipeInputStream extends SmbFileInputStream { + + private static final int INIT_PIPE_SIZE = 4096; + + private byte[] pipe_buf = new byte[INIT_PIPE_SIZE]; + private int beg_idx, nxt_idx, used; + private boolean dcePipe; + + Object lock; + + TransactNamedPipeInputStream( SmbNamedPipe pipe ) throws SmbException, + MalformedURLException, UnknownHostException { + super( pipe, ( pipe.pipeType & 0xFFFF00FF ) | SmbFile.O_EXCL ); + this.dcePipe = ( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT ) != SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT; + lock = new Object(); + } + public int read() throws IOException { + int result = -1; + + synchronized( lock ) { + try { + while( used == 0 ) { + lock.wait(); + } + } catch( InterruptedException ie ) { + throw new IOException( ie.getMessage() ); + } + result = pipe_buf[beg_idx] & 0xFF; + beg_idx = ( beg_idx + 1 ) % pipe_buf.length; + } + return result; + } + public int read( byte[] b ) throws IOException { + return read( b, 0, b.length ); + } + public int read( byte[] b, int off, int len ) throws IOException { + int result = -1; + int i; + + if( len <= 0 ) { + return 0; + } + synchronized( lock ) { + try { + while( used == 0 ) { + lock.wait(); + } + } catch( InterruptedException ie ) { + throw new IOException( ie.getMessage() ); + } + i = pipe_buf.length - beg_idx; + result = len > used ? used : len; + if( used > i && result > i ) { + System.arraycopy( pipe_buf, beg_idx, b, off, i ); + off += i; + System.arraycopy( pipe_buf, 0, b, off, result - i ); + } else { + System.arraycopy( pipe_buf, beg_idx, b, off, result ); + } + used -= result; + beg_idx = ( beg_idx + result ) % pipe_buf.length; + } + + return result; + } + public int available() throws IOException { + if( file.log.level >= 3 ) + file.log.println( "Named Pipe available() does not apply to TRANSACT Named Pipes" ); + return 0; + } + int receive( byte[] b, int off, int len ) { + int i; + + if( len > ( pipe_buf.length - used )) { + byte[] tmp; + int new_size; + + new_size = pipe_buf.length * 2; + if( len > ( new_size - used )) { + new_size = len + used; + } + tmp = pipe_buf; + pipe_buf = new byte[new_size]; + i = tmp.length - beg_idx; + if( used > i ) { /* 2 chunks */ + System.arraycopy( tmp, beg_idx, pipe_buf, 0, i ); + System.arraycopy( tmp, 0, pipe_buf, i, used - i ); + } else { + System.arraycopy( tmp, beg_idx, pipe_buf, 0, used ); + } + beg_idx = 0; + nxt_idx = used; + tmp = null; + } + + i = pipe_buf.length - nxt_idx; + if( len > i ) { + System.arraycopy( b, off, pipe_buf, nxt_idx, i ); + off += i; + System.arraycopy( b, off, pipe_buf, 0, len - i ); + } else { + System.arraycopy( b, off, pipe_buf, nxt_idx, len ); + } + nxt_idx = ( nxt_idx + len ) % pipe_buf.length; + used += len; + return len; + } + public int dce_read( byte[] b, int off, int len ) throws IOException { + return super.read(b, off, len); + } +} diff --git a/src/jcifs/smb/TransactNamedPipeOutputStream.java b/src/jcifs/smb/TransactNamedPipeOutputStream.java new file mode 100644 index 0000000..6250146 --- /dev/null +++ b/src/jcifs/smb/TransactNamedPipeOutputStream.java @@ -0,0 +1,69 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +import java.io.OutputStream; +import java.io.IOException; + +class TransactNamedPipeOutputStream extends SmbFileOutputStream { + + private String path; + private SmbNamedPipe pipe; + private byte[] tmp = new byte[1]; + private boolean dcePipe; + + TransactNamedPipeOutputStream( SmbNamedPipe pipe ) throws IOException { + super(pipe, false, (pipe.pipeType & 0xFFFF00FF) | SmbFile.O_EXCL); + this.pipe = pipe; + this.dcePipe = ( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT ) == SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT; + path = pipe.unc; + } + + public void close() throws IOException { + pipe.close(); + } + public void write( int b ) throws IOException { + tmp[0] = (byte)b; + write( tmp, 0, 1 ); + } + public void write( byte[] b ) throws IOException { + write( b, 0, b.length ); + } + public void write( byte[] b, int off, int len ) throws IOException { + if( len < 0 ) { + len = 0; + } + + if(( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_CALL ) == SmbNamedPipe.PIPE_TYPE_CALL ) { + pipe.send( new TransWaitNamedPipe( path ), + new TransWaitNamedPipeResponse() ); + pipe.send( new TransCallNamedPipe( path, b, off, len ), + new TransCallNamedPipeResponse( pipe )); + } else if(( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_TRANSACT ) == + SmbNamedPipe.PIPE_TYPE_TRANSACT ) { + ensureOpen(); + TransTransactNamedPipe req = new TransTransactNamedPipe( pipe.fid, b, off, len ); + if (dcePipe) { + req.maxDataCount = 1024; + } + pipe.send( req, new TransTransactNamedPipeResponse( pipe )); + } + } +} + diff --git a/src/jcifs/smb/WinError.java b/src/jcifs/smb/WinError.java new file mode 100644 index 0000000..41b026a --- /dev/null +++ b/src/jcifs/smb/WinError.java @@ -0,0 +1,61 @@ +/* jcifs smb client library in Java + * Copyright (C) 2004 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.smb; + +public interface WinError { + + /* Don't bother to edit this. Everthing within the interface + * block is automatically generated from the ntstatus package. + */ + + public static final int ERROR_SUCCESS = 0; + public static final int ERROR_ACCESS_DENIED = 5; + public static final int ERROR_REQ_NOT_ACCEP = 71; + public static final int ERROR_BAD_PIPE = 230; + public static final int ERROR_PIPE_BUSY = 231; + public static final int ERROR_NO_DATA = 232; + public static final int ERROR_PIPE_NOT_CONNECTED = 233; + public static final int ERROR_MORE_DATA = 234; + public static final int ERROR_NO_BROWSER_SERVERS_FOUND = 6118; + + static final int[] WINERR_CODES = { + ERROR_SUCCESS, + ERROR_ACCESS_DENIED, + ERROR_REQ_NOT_ACCEP, + ERROR_BAD_PIPE, + ERROR_PIPE_BUSY, + ERROR_NO_DATA, + ERROR_PIPE_NOT_CONNECTED, + ERROR_MORE_DATA, + ERROR_NO_BROWSER_SERVERS_FOUND, + }; + + static final String[] WINERR_MESSAGES = { + "The operation completed successfully.", + "Access is denied.", + "No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept.", + "The pipe state is invalid.", + "All pipe instances are busy.", + "The pipe is being closed.", + "No process is on the other end of the pipe.", + "More data is available.", + "The list of servers for this workgroup is not currently available.", + }; +} + diff --git a/src/jcifs/util/Base64.java b/src/jcifs/util/Base64.java new file mode 100644 index 0000000..9008667 --- /dev/null +++ b/src/jcifs/util/Base64.java @@ -0,0 +1,94 @@ +/* Encodes and decodes to and from Base64 notation. + * Copyright (C) 2003 "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.util; + +public class Base64 { + + private static final String ALPHABET = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + /** + * Base-64 encodes the supplied block of data. Line wrapping is not + * applied on output. + * + * @param bytes The block of data that is to be Base-64 encoded. + * @return A String containing the encoded data. + */ + public static String encode(byte[] bytes) { + int length = bytes.length; + if (length == 0) return ""; + StringBuffer buffer = + new StringBuffer((int) Math.ceil((double) length / 3d) * 4); + int remainder = length % 3; + length -= remainder; + int block; + int i = 0; + while (i < length) { + block = ((bytes[i++] & 0xff) << 16) | ((bytes[i++] & 0xff) << 8) | + (bytes[i++] & 0xff); + buffer.append(ALPHABET.charAt(block >>> 18)); + buffer.append(ALPHABET.charAt((block >>> 12) & 0x3f)); + buffer.append(ALPHABET.charAt((block >>> 6) & 0x3f)); + buffer.append(ALPHABET.charAt(block & 0x3f)); + } + if (remainder == 0) return buffer.toString(); + if (remainder == 1) { + block = (bytes[i] & 0xff) << 4; + buffer.append(ALPHABET.charAt(block >>> 6)); + buffer.append(ALPHABET.charAt(block & 0x3f)); + buffer.append("=="); + return buffer.toString(); + } + block = (((bytes[i++] & 0xff) << 8) | ((bytes[i]) & 0xff)) << 2; + buffer.append(ALPHABET.charAt(block >>> 12)); + buffer.append(ALPHABET.charAt((block >>> 6) & 0x3f)); + buffer.append(ALPHABET.charAt(block & 0x3f)); + buffer.append("="); + return buffer.toString(); + } + + /** + * Decodes the supplied Base-64 encoded string. + * + * @param string The Base-64 encoded string that is to be decoded. + * @return A byte[] containing the decoded data block. + */ + public static byte[] decode(String string) { + int length = string.length(); + if (length == 0) return new byte[0]; + int pad = (string.charAt(length - 2) == '=') ? 2 : + (string.charAt(length - 1) == '=') ? 1 : 0; + int size = length * 3 / 4 - pad; + byte[] buffer = new byte[size]; + int block; + int i = 0; + int index = 0; + while (i < length) { + block = (ALPHABET.indexOf(string.charAt(i++)) & 0xff) << 18 | + (ALPHABET.indexOf(string.charAt(i++)) & 0xff) << 12 | + (ALPHABET.indexOf(string.charAt(i++)) & 0xff) << 6 | + (ALPHABET.indexOf(string.charAt(i++)) & 0xff); + buffer[index++] = (byte) (block >>> 16); + if (index < size) buffer[index++] = (byte) ((block >>> 8) & 0xff); + if (index < size) buffer[index++] = (byte) (block & 0xff); + } + return buffer; + } + +} diff --git a/src/jcifs/util/DES.java b/src/jcifs/util/DES.java new file mode 100644 index 0000000..db2fa4b --- /dev/null +++ b/src/jcifs/util/DES.java @@ -0,0 +1,551 @@ +// DesCipher - the DES encryption method +// +// The meat of this code is by Dave Zimmerman , and is: +// +// Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. +// +// Permission to use, copy, modify, and distribute this software +// and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and +// without fee is hereby granted, provided that this copyright notice is kept +// intact. +// +// WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY +// OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE +// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR +// DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. +// +// THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE +// CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE +// PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT +// NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE +// SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE +// SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE +// PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP +// SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR +// HIGH RISK ACTIVITIES. +// +// +// The rest is: +// +// Copyright (C) 1996 by Jef Poskanzer . All rights reserved. +// +// Copyright (C) 1996 by Wolfgang Platzer +// email: wplatzer@iaik.tu-graz.ac.at +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. +// + +package jcifs.util; + +import java.io.*; + +/** + * This code is derived from the above source + * JCIFS API + * Norbert Hranitzky + * + *

and modified again by Michael B. Allen + */ + +public class DES { + + + private int[] encryptKeys = new int[32]; + private int[] decryptKeys = new int[32]; + + private int[] tempInts = new int[2]; + + + public DES( ) { + + } + + // Constructor, byte-array key. + public DES( byte[] key ) { + if( key.length == 7 ) { + byte[] key8 = new byte[8]; + makeSMBKey( key, key8 ); + setKey( key8 ); + } else { + setKey( key ); + } + } + + + public static void makeSMBKey(byte[] key7, byte[] key8) { + + int i; + + key8[0] = (byte) ( ( key7[0] >> 1) & 0xff); + key8[1] = (byte)(( ((key7[0] & 0x01) << 6) | (((key7[1] & 0xff)>>2) & 0xff)) & 0xff ); + key8[2] = (byte)(( ((key7[1] & 0x03) << 5) | (((key7[2] & 0xff)>>3) & 0xff)) & 0xff ); + key8[3] = (byte)(( ((key7[2] & 0x07) << 4) | (((key7[3] & 0xff)>>4) & 0xff)) & 0xff ); + key8[4] = (byte)(( ((key7[3] & 0x0F) << 3) | (((key7[4] & 0xff)>>5) & 0xff)) & 0xff ); + key8[5] = (byte)(( ((key7[4] & 0x1F) << 2) | (((key7[5] & 0xff)>>6) & 0xff)) & 0xff ); + key8[6] = (byte)(( ((key7[5] & 0x3F) << 1) | (((key7[6] & 0xff)>>7) & 0xff)) & 0xff ); + key8[7] = (byte)(key7[6] & 0x7F); + for (i=0;i<8;i++) { + key8[i] = (byte)( key8[i] << 1); + } + } + + /// Set the key. + public void setKey( byte[] key ) { + + // CHECK PAROTY TBD + deskey( key, true, encryptKeys ); + deskey( key, false, decryptKeys ); + } + + // Turn an 8-byte key into internal keys. + private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL ) { + + int i, j, l, m, n; + int[] pc1m = new int[56]; + int[] pcr = new int[56]; + int[] kn = new int[32]; + + for ( j = 0; j < 56; ++j ) { + l = pc1[j]; + m = l & 07; + pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0; + } + + for ( i = 0; i < 16; ++i ) { + + if ( encrypting ) + m = i << 1; + else + m = (15-i) << 1; + n = m+1; + kn[m] = kn[n] = 0; + for ( j = 0; j < 28; ++j ) { + l = j+totrot[i]; + if ( l < 28 ) + pcr[j] = pc1m[l]; + else + pcr[j] = pc1m[l-28]; + } + for ( j=28; j < 56; ++j ) { + l = j+totrot[i]; + if ( l < 56 ) + pcr[j] = pc1m[l]; + else + pcr[j] = pc1m[l-28]; + } + for ( j = 0; j < 24; ++j ) { + if ( pcr[pc2[j]] != 0 ) + kn[m] |= bigbyte[j]; + if ( pcr[pc2[j+24]] != 0 ) + kn[n] |= bigbyte[j]; + } + } + cookey( kn, KnL ); + } + + private void cookey( int[] raw, int KnL[] ) { + int raw0, raw1; + int rawi, KnLi; + int i; + + for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i ) { + raw0 = raw[rawi++]; + raw1 = raw[rawi++]; + KnL[KnLi] = (raw0 & 0x00fc0000) << 6; + KnL[KnLi] |= (raw0 & 0x00000fc0) << 10; + KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10; + KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6; + ++KnLi; + KnL[KnLi] = (raw0 & 0x0003f000) << 12; + KnL[KnLi] |= (raw0 & 0x0000003f) << 16; + KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4; + KnL[KnLi] |= (raw1 & 0x0000003f); + ++KnLi; + } + } + + + /// Encrypt a block of eight bytes. + private void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff ) { + + squashBytesToInts( clearText, clearOff, tempInts, 0, 2 ); + des( tempInts, tempInts, encryptKeys ); + spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 ); + } + + /// Decrypt a block of eight bytes. + private void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff ) { + + squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 ); + des( tempInts, tempInts, decryptKeys ); + spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 ); + } + + // The DES function. + private void des( int[] inInts, int[] outInts, int[] keys ) { + + int fval, work, right, leftt; + int round; + int keysi = 0; + + leftt = inInts[0]; + right = inInts[1]; + + work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f; + right ^= work; + leftt ^= (work << 4); + + work = ((leftt >>> 16) ^ right) & 0x0000ffff; + right ^= work; + leftt ^= (work << 16); + + work = ((right >>> 2) ^ leftt) & 0x33333333; + leftt ^= work; + right ^= (work << 2); + + work = ((right >>> 8) ^ leftt) & 0x00ff00ff; + leftt ^= work; + right ^= (work << 8); + right = (right << 1) | ((right >>> 31) & 1); + + work = (leftt ^ right) & 0xaaaaaaaa; + leftt ^= work; + right ^= work; + leftt = (leftt << 1) | ((leftt >>> 31) & 1); + + for ( round = 0; round < 8; ++round ) { + work = (right << 28) | (right >>> 4); + work ^= keys[keysi++]; + fval = SP7[ work & 0x0000003f ]; + fval |= SP5[(work >>> 8) & 0x0000003f ]; + fval |= SP3[(work >>> 16) & 0x0000003f ]; + fval |= SP1[(work >>> 24) & 0x0000003f ]; + work = right ^ keys[keysi++]; + fval |= SP8[ work & 0x0000003f ]; + fval |= SP6[(work >>> 8) & 0x0000003f ]; + fval |= SP4[(work >>> 16) & 0x0000003f ]; + fval |= SP2[(work >>> 24) & 0x0000003f ]; + leftt ^= fval; + work = (leftt << 28) | (leftt >>> 4); + work ^= keys[keysi++]; + fval = SP7[ work & 0x0000003f ]; + fval |= SP5[(work >>> 8) & 0x0000003f ]; + fval |= SP3[(work >>> 16) & 0x0000003f ]; + fval |= SP1[(work >>> 24) & 0x0000003f ]; + work = leftt ^ keys[keysi++]; + fval |= SP8[ work & 0x0000003f ]; + fval |= SP6[(work >>> 8) & 0x0000003f ]; + fval |= SP4[(work >>> 16) & 0x0000003f ]; + fval |= SP2[(work >>> 24) & 0x0000003f ]; + right ^= fval; + } + + right = (right << 31) | (right >>> 1); + work = (leftt ^ right) & 0xaaaaaaaa; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >>> 1); + work = ((leftt >>> 8) ^ right) & 0x00ff00ff; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >>> 2) ^ right) & 0x33333333; + right ^= work; + leftt ^= (work << 2); + work = ((right >>> 16) ^ leftt) & 0x0000ffff; + leftt ^= work; + right ^= (work << 16); + work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f; + leftt ^= work; + right ^= (work << 4); + outInts[0] = right; + outInts[1] = leftt; + } + + + /// Encrypt a block of bytes. + public void encrypt( byte[] clearText, byte[] cipherText ) { + encrypt( clearText, 0, cipherText, 0 ); + } + + /// Decrypt a block of bytes. + public void decrypt( byte[] cipherText, byte[] clearText ) { + + decrypt( cipherText, 0, clearText, 0 ); + } + + /** + * encrypts an array where the length must be a multiple of 8 + */ + public byte[] encrypt(byte[] clearText) { + + int length = clearText.length; + + if (length % 8 != 0) { + System.out.println("Array must be a multiple of 8"); + return null; + } + + byte[] cipherText = new byte[length]; + int count = length / 8; + + for (int i=0; i>> 24 ); + outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 ); + outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 ); + outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i]; + } + } +} diff --git a/src/jcifs/util/Encdec.java b/src/jcifs/util/Encdec.java new file mode 100644 index 0000000..33fb351 --- /dev/null +++ b/src/jcifs/util/Encdec.java @@ -0,0 +1,314 @@ +/* encdec - encode and decode integers, times, and + * internationalized strings to and from popular binary formats + * http://www.ioplex.com/~miallen/encdec/ + * Copyright (c) 2003 Michael B. Allen + * + * The GNU Library General Public License + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA + */ + +package jcifs.util; + +import java.util.Date; +import java.io.IOException; + +public class Encdec { + + public static final long MILLISECONDS_BETWEEN_1970_AND_1601 = 11644473600000L; + public static final long SEC_BETWEEEN_1904_AND_1970 = 2082844800L; + public static final int TIME_1970_SEC_32BE = 1; + public static final int TIME_1970_SEC_32LE = 2; + public static final int TIME_1904_SEC_32BE = 3; + public static final int TIME_1904_SEC_32LE = 4; + public static final int TIME_1601_NANOS_64LE = 5; + public static final int TIME_1601_NANOS_64BE = 6; + public static final int TIME_1970_MILLIS_64BE = 7; + public static final int TIME_1970_MILLIS_64LE = 8; + + /* Encode integers + */ + + public static int enc_uint16be( short s, byte[] dst, int di ) { + dst[di++] = (byte)((s >> 8) & 0xFF); + dst[di] = (byte)(s & 0xFF); + return 2; + } + public static int enc_uint32be( int i, byte[] dst, int di ) { + dst[di++] = (byte)((i >> 24) & 0xFF); + dst[di++] = (byte)((i >> 16) & 0xFF); + dst[di++] = (byte)((i >> 8) & 0xFF); + dst[di] = (byte)(i & 0xFF); + return 4; + } + public static int enc_uint16le( short s, byte[] dst, int di ) + { + dst[di++] = (byte)(s & 0xFF); + dst[di] = (byte)((s >> 8) & 0xFF); + return 2; + } + public static int enc_uint32le( int i, byte[] dst, int di ) + { + dst[di++] = (byte)(i & 0xFF); + dst[di++] = (byte)((i >> 8) & 0xFF); + dst[di++] = (byte)((i >> 16) & 0xFF); + dst[di] = (byte)((i >> 24) & 0xFF); + return 4; + } + + /* Decode integers + */ + + public static short dec_uint16be( byte[] src, int si ) + { + return (short)(((src[si] & 0xFF) << 8) | (src[si + 1] & 0xFF)); + } + public static int dec_uint32be( byte[] src, int si ) + { + return ((src[si] & 0xFF) << 24) | ((src[si + 1] & 0xFF) << 16) | + ((src[si + 2] & 0xFF) << 8) | (src[si + 3] & 0xFF); + } + public static short dec_uint16le( byte[] src, int si ) + { + return (short)((src[si] & 0xFF) | ((src[si + 1] & 0xFF) << 8)); + } + public static int dec_uint32le( byte[] src, int si ) + { + return (src[si] & 0xFF) | ((src[si + 1] & 0xFF) << 8) | + ((src[si + 2] & 0xFF) << 16) | ((src[si + 3] & 0xFF) << 24); + } + + /* Encode and decode 64 bit integers + */ + + public static int enc_uint64be( long l, byte[] dst, int di ) + { + enc_uint32be( (int)(l & 0xFFFFFFFFL), dst, di + 4 ); + enc_uint32be( (int)(( l >> 32L ) & 0xFFFFFFFFL), dst, di ); + return 8; + } + public static int enc_uint64le( long l, byte[] dst, int di ) + { + enc_uint32le( (int)(l & 0xFFFFFFFFL), dst, di ); + enc_uint32le( (int)(( l >> 32L ) & 0xFFFFFFFFL), dst, di + 4 ); + return 8; + } + public static long dec_uint64be( byte[] src, int si ) + { + long l; + l = dec_uint32be( src, si ) & 0xFFFFFFFFL; + l <<= 32L; + l |= dec_uint32be( src, si + 4 ) & 0xFFFFFFFFL; + return l; + } + public static long dec_uint64le( byte[] src, int si ) + { + long l; + l = dec_uint32le( src, si + 4 ) & 0xFFFFFFFFL; + l <<= 32L; + l |= dec_uint32le( src, si ) & 0xFFFFFFFFL; + return l; + } + + /* Encode floats + */ + + public static int enc_floatle( float f, byte[] dst, int di ) + { + return enc_uint32le( Float.floatToIntBits( f ), dst, di ); + } + public static int enc_floatbe( float f, byte[] dst, int di ) + { + return enc_uint32be( Float.floatToIntBits( f ), dst, di ); + } + + /* Decode floating point numbers + */ + + public static float dec_floatle( byte[] src, int si ) + { + return Float.intBitsToFloat( dec_uint32le( src, si )); + } + public static float dec_floatbe( byte[] src, int si ) + { + return Float.intBitsToFloat( dec_uint32be( src, si )); + } + + /* Encode and decode doubles + */ + + public static int enc_doublele( double d, byte[] dst, int di ) + { + return enc_uint64le( Double.doubleToLongBits( d ), dst, di ); + } + public static int enc_doublebe( double d, byte[] dst, int di ) + { + return enc_uint64be( Double.doubleToLongBits( d ), dst, di ); + } + public static double dec_doublele( byte[] src, int si ) + { + return Double.longBitsToDouble( dec_uint64le( src, si )); + } + public static double dec_doublebe( byte[] src, int si ) + { + return Double.longBitsToDouble( dec_uint64be( src, si )); + } + + /* Encode times + */ + + public static int enc_time( Date date, byte[] dst, int di, int enc ) + { + long t; + + switch( enc ) { + case TIME_1970_SEC_32BE: + return enc_uint32be( (int)(date.getTime() / 1000L), dst, di ); + case TIME_1970_SEC_32LE: + return enc_uint32le( (int)(date.getTime() / 1000L), dst, di ); + case TIME_1904_SEC_32BE: + return enc_uint32be( (int)((date.getTime() / 1000L + + SEC_BETWEEEN_1904_AND_1970) & 0xFFFFFFFF), dst, di ); + case TIME_1904_SEC_32LE: + return enc_uint32le( (int)((date.getTime() / 1000L + + SEC_BETWEEEN_1904_AND_1970) & 0xFFFFFFFF), dst, di ); + case TIME_1601_NANOS_64BE: + t = (date.getTime() + MILLISECONDS_BETWEEN_1970_AND_1601) * 10000L; + return enc_uint64be( t, dst, di ); + case TIME_1601_NANOS_64LE: + t = (date.getTime() + MILLISECONDS_BETWEEN_1970_AND_1601) * 10000L; + return enc_uint64le( t, dst, di ); + case TIME_1970_MILLIS_64BE: + return enc_uint64be( date.getTime(), dst, di ); + case TIME_1970_MILLIS_64LE: + return enc_uint64le( date.getTime(), dst, di ); + default: + throw new IllegalArgumentException( "Unsupported time encoding" ); + } + } + + /* Decode times + */ + + public static Date dec_time( byte[] src, int si, int enc ) + { + long t; + + switch( enc ) { + case TIME_1970_SEC_32BE: + return new Date( dec_uint32be( src, si ) * 1000L ); + case TIME_1970_SEC_32LE: + return new Date( dec_uint32le( src, si ) * 1000L ); + case TIME_1904_SEC_32BE: + return new Date((( dec_uint32be( src, si ) & 0xFFFFFFFFL) - + SEC_BETWEEEN_1904_AND_1970 ) * 1000L ); + case TIME_1904_SEC_32LE: + return new Date((( dec_uint32le( src, si ) & 0xFFFFFFFFL) - + SEC_BETWEEEN_1904_AND_1970 ) * 1000L ); + case TIME_1601_NANOS_64BE: + t = dec_uint64be( src, si ); + return new Date( t / 10000L - MILLISECONDS_BETWEEN_1970_AND_1601); + case TIME_1601_NANOS_64LE: + t = dec_uint64le( src, si ); + return new Date( t / 10000L - MILLISECONDS_BETWEEN_1970_AND_1601); + case TIME_1970_MILLIS_64BE: + return new Date( dec_uint64be( src, si )); + case TIME_1970_MILLIS_64LE: + return new Date( dec_uint64le( src, si )); + default: + throw new IllegalArgumentException( "Unsupported time encoding" ); + } + } + + public static int enc_utf8( String str, byte[] dst, int di, int dlim ) throws IOException { + int start = di, ch; + int strlen = str.length(); + + for( int i = 0; di < dlim && i < strlen; i++ ) { + ch = str.charAt( i ); + if ((ch >= 0x0001) && (ch <= 0x007F)) { + dst[di++] = (byte)ch; + } else if (ch > 0x07FF) { + if((dlim - di) < 3 ) { + break; + } + dst[di++] = (byte)(0xE0 | ((ch >> 12) & 0x0F)); + dst[di++] = (byte)(0x80 | ((ch >> 6) & 0x3F)); + dst[di++] = (byte)(0x80 | ((ch >> 0) & 0x3F)); + } else { + if((dlim - di) < 2 ) { + break; + } + dst[di++] = (byte)(0xC0 | ((ch >> 6) & 0x1F)); + dst[di++] = (byte)(0x80 | ((ch >> 0) & 0x3F)); + } + } + + return di - start; + } + public static String dec_utf8( byte[] src, int si, int slim ) throws IOException { + char[] uni = new char[slim - si]; + int ui, ch; + + for( ui = 0; si < slim && (ch = src[si++] & 0xFF) != 0; ui++ ) { + if( ch < 0x80 ) { + uni[ui] = (char)ch; + } else if((ch & 0xE0) == 0xC0 ) { + if((slim - si) < 2 ) { + break; + } + uni[ui] = (char)((ch & 0x1F) << 6); + ch = src[si++] & 0xFF; + uni[ui] |= ch & 0x3F; + if ((ch & 0xC0) != 0x80 || uni[ui] < 0x80 ) { + throw new IOException( "Invalid UTF-8 sequence" ); + } + } else if((ch & 0xF0) == 0xE0 ) { + if((slim - si) < 3 ) { + break; + } + uni[ui] = (char)((ch & 0x0F) << 12); + ch = src[si++] & 0xFF; + if ((ch & 0xC0) != 0x80 ) { + throw new IOException( "Invalid UTF-8 sequence" ); + } else { + uni[ui] |= (ch & 0x3F) << 6; + ch = src[si++] & 0xFF; + uni[ui] |= ch & 0x3F; + if ((ch & 0xC0) != 0x80 || uni[ui] < 0x800) { + throw new IOException( "Invalid UTF-8 sequence" ); + } + } + } else { + throw new IOException( "Unsupported UTF-8 sequence" ); + } + } + + return new String( uni, 0, ui ); + } + public static String dec_ucs2le( byte[] src, int si, int slim, char[] buf ) throws IOException { + int bi; + + for( bi = 0; (si + 1) < slim; bi++, si += 2 ) { + buf[bi] = (char)dec_uint16le( src, si ); + if( buf[bi] == '\0' ) { + break; + } + } + + return new String( buf, 0, bi ); + } +} diff --git a/src/jcifs/util/HMACT64.java b/src/jcifs/util/HMACT64.java new file mode 100644 index 0000000..8420fb9 --- /dev/null +++ b/src/jcifs/util/HMACT64.java @@ -0,0 +1,116 @@ +/* HMACT64 keyed hashing algorithm + * Copyright (C) 2003 "Eric Glass" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.util; + +import java.security.MessageDigest; + +/** + * This is an implementation of the HMACT64 keyed hashing algorithm. + * HMACT64 is defined by Luke Leighton as a modified HMAC-MD5 (RFC 2104) + * in which the key is truncated at 64 bytes (rather than being hashed + * via MD5). + */ +public class HMACT64 extends MessageDigest implements Cloneable { + + private static final int BLOCK_LENGTH = 64; + + private static final byte IPAD = (byte) 0x36; + + private static final byte OPAD = (byte) 0x5c; + + private MessageDigest md5; + + private byte[] ipad = new byte[BLOCK_LENGTH]; + + private byte[] opad = new byte[BLOCK_LENGTH]; + + /** + * Creates an HMACT64 instance which uses the given secret key material. + * + * @param key The key material to use in hashing. + */ + public HMACT64(byte[] key) { + super("HMACT64"); + int length = Math.min(key.length, BLOCK_LENGTH); + for (int i = 0; i < length; i++) { + ipad[i] = (byte) (key[i] ^ IPAD); + opad[i] = (byte) (key[i] ^ OPAD); + } + for (int i = length; i < BLOCK_LENGTH; i++) { + ipad[i] = IPAD; + opad[i] = OPAD; + } + try { + md5 = MessageDigest.getInstance("MD5"); + } catch (Exception ex) { + throw new IllegalStateException(ex.getMessage()); + } + engineReset(); + } + + private HMACT64(HMACT64 hmac) throws CloneNotSupportedException { + super("HMACT64"); + this.ipad = hmac.ipad; + this.opad = hmac.opad; + this.md5 = (MessageDigest) hmac.md5.clone(); + } + + public Object clone() { + try { + return new HMACT64(this); + } catch (CloneNotSupportedException ex) { + throw new IllegalStateException(ex.getMessage()); + } + } + + protected byte[] engineDigest() { + byte[] digest = md5.digest(); + md5.update(opad); + return md5.digest(digest); + } + + protected int engineDigest(byte[] buf, int offset, int len) { + byte[] digest = md5.digest(); + md5.update(opad); + md5.update(digest); + try { + return md5.digest(buf, offset, len); + } catch (Exception ex) { + throw new IllegalStateException(); + } + } + + protected int engineGetDigestLength() { + return md5.getDigestLength(); + } + + protected void engineReset() { + md5.reset(); + md5.update(ipad); + } + + protected void engineUpdate(byte b) { + md5.update(b); + } + + protected void engineUpdate(byte[] input, int offset, int len) { + md5.update(input, offset, len); + } + +} diff --git a/src/jcifs/util/Hexdump.java b/src/jcifs/util/Hexdump.java new file mode 100644 index 0000000..44f706d --- /dev/null +++ b/src/jcifs/util/Hexdump.java @@ -0,0 +1,160 @@ +/* jcifs smb client library in Java + * Copyright (C) 2000 "Michael B. Allen" + * "Christopher R. Hertel" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.util; + +import java.io.OutputStream; +import java.io.PrintStream; + +/** + */ + +public class Hexdump { + + private static final String NL = System.getProperty( "line.separator" ); + private static final int NL_LENGTH = NL.length(); + + private static final char[] SPACE_CHARS = { + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' + }; + + public static final char[] HEX_DIGITS = { + '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'A', 'B', + 'C', 'D', 'E', 'F' + }; + +/** + * Generate "hexdump" output of the buffer at src like the following: + * + *

+ * 00000: 04 d2 29 00 00 01 00 00 00 00 00 01 20 45 47 46  |..)......... EGF|
+ * 00010: 43 45 46 45 45 43 41 43 41 43 41 43 41 43 41 43  |CEFEECACACACACAC|
+ * 00020: 41 43 41 43 41 43 41 43 41 43 41 41 44 00 00 20  |ACACACACACAAD.. |
+ * 00030: 00 01 c0 0c 00 20 00 01 00 00 00 00 00 06 20 00  |..... ........ .|
+ * 00040: ac 22 22 e1                                      |."".            |
+ * 
+ */ + + public static void hexdump( PrintStream ps, byte[] src, int srcIndex, int length ) { + if( length == 0 ) { + return; + } + + int s = length % 16; + int r = ( s == 0 ) ? length / 16 : length / 16 + 1; + char[] c = new char[r * (74 + NL_LENGTH)]; + char[] d = new char[16]; + int i; + int si = 0; + int ci = 0; + + do { + toHexChars( si, c, ci, 5 ); + ci += 5; + c[ci++] = ':'; + do { + if( si == length ) { + int n = 16 - s; + System.arraycopy( SPACE_CHARS, 0, c, ci, n * 3 ); + ci += n * 3; + System.arraycopy( SPACE_CHARS, 0, d, s, n ); + break; + } + c[ci++] = ' '; + i = src[srcIndex + si] & 0xFF; + toHexChars( i, c, ci, 2 ); + ci += 2; + if( i < 0 || Character.isISOControl( (char)i )) { + d[si % 16] = '.'; + } else { + d[si % 16] = (char)i; + } + } while(( ++si % 16 ) != 0 ); + c[ci++] = ' '; + c[ci++] = ' '; + c[ci++] = '|'; + System.arraycopy( d, 0, c, ci, 16 ); + ci += 16; + c[ci++] = '|'; + NL.getChars( 0, NL_LENGTH, c, ci ); + ci += NL_LENGTH; + } while( si < length ); + + ps.println( c ); + } + +/** + * This is an alternative to the java.lang.Integer.toHexString + * method. It is an efficient relative that also will pad the left side so + * that the result is size digits. + */ + public static String toHexString( int val, int size ) { + char[] c = new char[size]; + toHexChars( val, c, 0, size ); + return new String( c ); + } + public static String toHexString( long val, int size ) { + char[] c = new char[size]; + toHexChars( val, c, 0, size ); + return new String( c ); + } + public static String toHexString( byte[] src, int srcIndex, int size ) { + char[] c = new char[size]; + size = ( size % 2 == 0 ) ? size / 2 : size / 2 + 1; + for( int i = 0, j = 0; i < size; i++ ) { + c[j++] = HEX_DIGITS[(src[i] >> 4 ) & 0x0F]; + if( j == c.length ) { + break; + } + c[j++] = HEX_DIGITS[src[i] & 0x0F]; + } + return new String( c ); + } + +/** + * This is the same as {@link jcifs.util.Hexdump#toHexString(int val, int + * size)} but provides a more practical form when trying to avoid {@link + * java.lang.String} concatenation and {@link java.lang.StringBuffer}. + */ + public static void toHexChars( int val, char dst[], int dstIndex, int size ) { + while( size > 0 ) { + int i = dstIndex + size - 1; + if( i < dst.length ) { + dst[i] = HEX_DIGITS[val & 0x000F]; + } + if( val != 0 ) { + val >>>= 4; + } + size--; + } + } + public static void toHexChars( long val, char dst[], int dstIndex, int size ) { + while( size > 0 ) { + dst[dstIndex + size - 1] = HEX_DIGITS[(int)( val & 0x000FL )]; + if( val != 0 ) { + val >>>= 4; + } + size--; + } + } +} + diff --git a/src/jcifs/util/LogStream.java b/src/jcifs/util/LogStream.java new file mode 100644 index 0000000..7037153 --- /dev/null +++ b/src/jcifs/util/LogStream.java @@ -0,0 +1,58 @@ +/* jcifs smb client library in Java + * Copyright (C) 2004 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.util; + +import java.io.PrintStream; + +/** +0 - nothing +1 - critical [default] +2 - basic info can be logged under load +3 - almost everything +N - debugging + */ + +public class LogStream extends PrintStream { + + private static LogStream inst; + + public static int level = 1; + + public LogStream( PrintStream stream ) { + super( stream ); + } + + public static void setLevel( int level ) { + LogStream.level = level; + } + /** + * This must be called before getInstance is called or + * it will have no effect. + */ + public static void setInstance( PrintStream stream ) { + inst = new LogStream( stream ); + } + public static LogStream getInstance() { + if( inst == null ) { + setInstance( System.err ); + } + return inst; + } +} + diff --git a/src/jcifs/util/MD4.java b/src/jcifs/util/MD4.java new file mode 100644 index 0000000..a99d39d --- /dev/null +++ b/src/jcifs/util/MD4.java @@ -0,0 +1,299 @@ +// This file is currently unlocked (change this line if you lock the file) +// +// $Log: MD4.java,v $ +// Revision 1.2 1998/01/05 03:41:19 iang +// Added references only. +// +// Revision 1.1.1.1 1997/11/03 22:36:56 hopwood +// + Imported to CVS (tagged as 'start'). +// +// Revision 0.1.0.0 1997/07/14 R. Naffah +// + original version +// +// $Endlog$ +/* + * Copyright (c) 1997 Systemics Ltd + * on behalf of the Cryptix Development Team. All rights reserved. + */ + +package jcifs.util; + +import java.security.MessageDigest; + +/** + * Implements the MD4 message digest algorithm in Java. + *

+ * References: + *

    + *
  1. Ronald L. Rivest, + * " + * The MD4 Message-Digest Algorithm", + * IETF RFC-1320 (informational). + *
+ * + *

$Revision: 1.2 $ + * @author Raif S. Naffah + */ +public class MD4 extends MessageDigest implements Cloneable +{ +// MD4 specific object variables +//........................................................................... + + /** + * The size in bytes of the input block to the tranformation algorithm. + */ + private static final int BLOCK_LENGTH = 64; // = 512 / 8; + + /** + * 4 32-bit words (interim result) + */ + private int[] context = new int[4]; + + /** + * Number of bytes processed so far mod. 2 power of 64. + */ + private long count; + + /** + * 512 bits input buffer = 16 x 32-bit words holds until reaches 512 bits. + */ + private byte[] buffer = new byte[BLOCK_LENGTH]; + + /** + * 512 bits work buffer = 16 x 32-bit words + */ + private int[] X = new int[16]; + + +// Constructors +//........................................................................... + + public MD4 () { + super("MD4"); + engineReset(); + } + + /** + * This constructor is here to implement cloneability of this class. + */ + private MD4 (MD4 md) { + this(); + context = (int[])md.context.clone(); + buffer = (byte[])md.buffer.clone(); + count = md.count; + } + + +// Cloneable method implementation +//........................................................................... + + /** + * Returns a copy of this MD object. + */ + public Object clone() { return new MD4(this); } + + +// JCE methods +//........................................................................... + + /** + * Resets this object disregarding any temporary data present at the + * time of the invocation of this call. + */ + public void engineReset () { + // initial values of MD4 i.e. A, B, C, D + // as per rfc-1320; they are low-order byte first + context[0] = 0x67452301; + context[1] = 0xEFCDAB89; + context[2] = 0x98BADCFE; + context[3] = 0x10325476; + count = 0L; + for (int i = 0; i < BLOCK_LENGTH; i++) + buffer[i] = 0; + } + + /** + * Continues an MD4 message digest using the input byte. + */ + public void engineUpdate (byte b) { + // compute number of bytes still unhashed; ie. present in buffer + int i = (int)(count % BLOCK_LENGTH); + count++; // update number of bytes + buffer[i] = b; + if (i == BLOCK_LENGTH - 1) + transform(buffer, 0); + } + + /** + * MD4 block update operation. + *

+ * Continues an MD4 message digest operation, by filling the buffer, + * transform(ing) data in 512-bit message block(s), updating the variables + * context and count, and leaving (buffering) the remaining bytes in buffer + * for the next update or finish. + * + * @param input input block + * @param offset start of meaningful bytes in input + * @param len count of bytes in input block to consider + */ + public void engineUpdate (byte[] input, int offset, int len) { + // make sure we don't exceed input's allocated size/length + if (offset < 0 || len < 0 || (long)offset + len > input.length) + throw new ArrayIndexOutOfBoundsException(); + + // compute number of bytes still unhashed; ie. present in buffer + int bufferNdx = (int)(count % BLOCK_LENGTH); + count += len; // update number of bytes + int partLen = BLOCK_LENGTH - bufferNdx; + int i = 0; + if (len >= partLen) { + System.arraycopy(input, offset, buffer, bufferNdx, partLen); + + + transform(buffer, 0); + + for (i = partLen; i + BLOCK_LENGTH - 1 < len; i+= BLOCK_LENGTH) + transform(input, offset + i); + bufferNdx = 0; + } + // buffer remaining input + if (i < len) + System.arraycopy(input, offset + i, buffer, bufferNdx, len - i); + } + + /** + * Completes the hash computation by performing final operations such + * as padding. At the return of this engineDigest, the MD engine is + * reset. + * + * @return the array of bytes for the resulting hash value. + */ + public byte[] engineDigest () { + // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512 + int bufferNdx = (int)(count % BLOCK_LENGTH); + int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx); + + // padding is alwas binary 1 followed by binary 0s + byte[] tail = new byte[padLen + 8]; + tail[0] = (byte)0x80; + + // append length before final transform: + // save number of bits, casting the long to an array of 8 bytes + // save low-order byte first. + for (int i = 0; i < 8; i++) + tail[padLen + i] = (byte)((count * 8) >>> (8 * i)); + + engineUpdate(tail, 0, tail.length); + + byte[] result = new byte[16]; + // cast this MD4's context (array of 4 ints) into an array of 16 bytes. + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + result[i * 4 + j] = (byte)(context[i] >>> (8 * j)); + + // reset the engine + engineReset(); + return result; + } + + +// own methods +//........................................................................... + + /** + * MD4 basic transformation. + *

+ * Transforms context based on 512 bits from input block starting + * from the offset'th byte. + * + * @param block input sub-array. + * @param offset starting position of sub-array. + */ + private void transform (byte[] block, int offset) { + + // encodes 64 bytes from input block into an array of 16 32-bit + // entities. Use A as a temp var. + for (int i = 0; i < 16; i++) + X[i] = (block[offset++] & 0xFF) | + (block[offset++] & 0xFF) << 8 | + (block[offset++] & 0xFF) << 16 | + (block[offset++] & 0xFF) << 24; + + + int A = context[0]; + int B = context[1]; + int C = context[2]; + int D = context[3]; + + A = FF(A, B, C, D, X[ 0], 3); + D = FF(D, A, B, C, X[ 1], 7); + C = FF(C, D, A, B, X[ 2], 11); + B = FF(B, C, D, A, X[ 3], 19); + A = FF(A, B, C, D, X[ 4], 3); + D = FF(D, A, B, C, X[ 5], 7); + C = FF(C, D, A, B, X[ 6], 11); + B = FF(B, C, D, A, X[ 7], 19); + A = FF(A, B, C, D, X[ 8], 3); + D = FF(D, A, B, C, X[ 9], 7); + C = FF(C, D, A, B, X[10], 11); + B = FF(B, C, D, A, X[11], 19); + A = FF(A, B, C, D, X[12], 3); + D = FF(D, A, B, C, X[13], 7); + C = FF(C, D, A, B, X[14], 11); + B = FF(B, C, D, A, X[15], 19); + + A = GG(A, B, C, D, X[ 0], 3); + D = GG(D, A, B, C, X[ 4], 5); + C = GG(C, D, A, B, X[ 8], 9); + B = GG(B, C, D, A, X[12], 13); + A = GG(A, B, C, D, X[ 1], 3); + D = GG(D, A, B, C, X[ 5], 5); + C = GG(C, D, A, B, X[ 9], 9); + B = GG(B, C, D, A, X[13], 13); + A = GG(A, B, C, D, X[ 2], 3); + D = GG(D, A, B, C, X[ 6], 5); + C = GG(C, D, A, B, X[10], 9); + B = GG(B, C, D, A, X[14], 13); + A = GG(A, B, C, D, X[ 3], 3); + D = GG(D, A, B, C, X[ 7], 5); + C = GG(C, D, A, B, X[11], 9); + B = GG(B, C, D, A, X[15], 13); + + A = HH(A, B, C, D, X[ 0], 3); + D = HH(D, A, B, C, X[ 8], 9); + C = HH(C, D, A, B, X[ 4], 11); + B = HH(B, C, D, A, X[12], 15); + A = HH(A, B, C, D, X[ 2], 3); + D = HH(D, A, B, C, X[10], 9); + C = HH(C, D, A, B, X[ 6], 11); + B = HH(B, C, D, A, X[14], 15); + A = HH(A, B, C, D, X[ 1], 3); + D = HH(D, A, B, C, X[ 9], 9); + C = HH(C, D, A, B, X[ 5], 11); + B = HH(B, C, D, A, X[13], 15); + A = HH(A, B, C, D, X[ 3], 3); + D = HH(D, A, B, C, X[11], 9); + C = HH(C, D, A, B, X[ 7], 11); + B = HH(B, C, D, A, X[15], 15); + + context[0] += A; + context[1] += B; + context[2] += C; + context[3] += D; + } + + // The basic MD4 atomic functions. + + private int FF (int a, int b, int c, int d, int x, int s) { + int t = a + ((b & c) | (~b & d)) + x; + return t << s | t >>> (32 - s); + } + private int GG (int a, int b, int c, int d, int x, int s) { + int t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999; + return t << s | t >>> (32 - s); + } + private int HH (int a, int b, int c, int d, int x, int s) { + int t = a + (b ^ c ^ d) + x + 0x6ED9EBA1; + return t << s | t >>> (32 - s); + } +} diff --git a/src/jcifs/util/MimeMap.java b/src/jcifs/util/MimeMap.java new file mode 100644 index 0000000..a96b359 --- /dev/null +++ b/src/jcifs/util/MimeMap.java @@ -0,0 +1,123 @@ +/* jcifs smb client library in Java + * Copyright (C) 2002 "Michael B. Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.util; + +import java.io.InputStream; +import java.io.IOException; + +public class MimeMap { + + private static final int IN_SIZE = 7000; + + private static final int ST_START = 1; + private static final int ST_COMM = 2; + private static final int ST_TYPE = 3; + private static final int ST_GAP = 4; + private static final int ST_EXT = 5; + + private byte[] in; + private int inLen; + + public MimeMap() throws IOException { + int n; + + in = new byte[IN_SIZE]; + InputStream is = getClass().getClassLoader().getResourceAsStream( "jcifs/util/mime.map" ); + + inLen = 0; + while(( n = is.read( in, inLen, IN_SIZE - inLen )) != -1 ) { + inLen += n; + } + if( inLen < 100 || inLen == IN_SIZE ) { + throw new IOException( "Error reading jcifs/util/mime.map resource" ); + } + is.close(); + } + + public String getMimeType( String extension ) throws IOException { + return getMimeType( extension, "application/octet-stream" ); + } + public String getMimeType( String extension, String def ) throws IOException { + int state, t, x, i, off; + byte ch; + byte[] type = new byte[128]; + byte[] buf = new byte[16]; + byte[] ext = extension.toLowerCase().getBytes( "ASCII" ); + + state = ST_START; + t = x = i = 0; + for( off = 0; off < inLen; off++ ) { + ch = in[off]; + switch( state ) { + case ST_START: + if( ch == ' ' || ch == '\t' ) { + break; + } else if( ch == '#' ) { + state = ST_COMM; + break; + } + state = ST_TYPE; + case ST_TYPE: + if( ch == ' ' || ch == '\t' ) { + state = ST_GAP; + } else { + type[t++] = ch; + } + break; + case ST_COMM: + if( ch == '\n' ) { + t = x = i = 0; + state = ST_START; + } + break; + case ST_GAP: + if( ch == ' ' || ch == '\t' ) { + break; + } + state = ST_EXT; + case ST_EXT: + switch( ch ) { + case ' ': + case '\t': + case '\n': + case '#': + for( i = 0; i < x && x == ext.length && buf[i] == ext[i]; i++ ) { + ; + } + if( i == ext.length ) { + return new String( type, 0, t, "ASCII" ); + } + if( ch == '#' ) { + state = ST_COMM; + } else if( ch == '\n' ) { + t = x = i = 0; + state = ST_START; + } + x = 0; + break; + default: + buf[x++] = ch; + } + break; + } + } + return def; + } +} + diff --git a/src/jcifs/util/RC4.java b/src/jcifs/util/RC4.java new file mode 100644 index 0000000..c3a7452 --- /dev/null +++ b/src/jcifs/util/RC4.java @@ -0,0 +1,64 @@ +/* Copyright (C) 2009 "Michael B Allen" + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package jcifs.util; + +public class RC4 +{ + + byte[] s; + int i, j; + + public RC4() + { + } + public RC4(byte[] key) + { + init(key, 0, key.length); + } + + public void init(byte[] key, int ki, int klen) + { + s = new byte[256]; + + for (i = 0; i < 256; i++) + s[i] = (byte)i; + + for (i = j = 0; i < 256; i++) { + j = (j + key[ki + i % klen] + s[i]) & 0xff; + byte t = s[i]; + s[i] = s[j]; + s[j] = t; + } + + i = j = 0; + } + public void update(byte[] src, int soff, int slen, byte[] dst, int doff) + { + int slim; + + slim = soff + slen; + while (soff < slim) { + i = (i + 1) & 0xff; + j = (j + s[i]) & 0xff; + byte t = s[i]; + s[i] = s[j]; + s[j] = t; + dst[doff++] = (byte)(src[soff++] ^ s[(s[i] + s[j]) & 0xff]); + } + } +} diff --git a/src/jcifs/util/mime.map b/src/jcifs/util/mime.map new file mode 100644 index 0000000..45d066c --- /dev/null +++ b/src/jcifs/util/mime.map @@ -0,0 +1,94 @@ +application/access mdf # Microsoft Access +#application/excel xls # Microsoft Excel +application/vnd.ms-excel xls # Microsoft Excel +application/font-tdpfr pfr # TrueDoc Portable Font Resource +application/futuresplash spl # Macromedia Flash +application/hep hep # Hummingbird Host Explorer Profiles +application/lotus-123 wks # Lotus 123 +application/mac-binhex40 hqx # Macintosh binhexed archives +application/mspowerpoint ppt # Microsoft Powerpoint +application/msword doc # Microsoft Word +application/octet-stream bin exe ani # Binary File +application/oda oda +application/pagemaker pm5 pt5 pm # PageMaker +application/pdf pdf # Adobe Acrobat +application/postscript ai eps ps # Postscript File +application/rtf rtf # Rich Text File +application/toolbook tbk # Toolbook +application/wordperfect wp # WordPerfect +application/wordperfect5.1 wp5 # WordPerfect Version 5.1 +application/wordperfect6.1 wp6 # WordPerfect Version 6.1 +application/wordperfectd wpd # WordPerfect +application/x-bcpio bcpio # +application/x-cpio cpio # +application/x-csh csh # C-Shell Program +application/x-director dcr # Director File +application/x-dvi dvi # TeX dvi Format +application/x-gtar gtar # Gzip and Tar file +application/x-gzip gz tgz # Gzip and Tar file +application/x-compress z # Gzip and Tar file +application/x-hdf hdf # NCSA HDF +application/x-ica ica # WinFrames +application/x-javascript js # Javascript +application/x-latex latex # Latex File +application/x-mif mif # +application/x-netcdf nc cdf # +#application/x-sh sh # sh Shell Program +application/x-shar shar # +application/x-shockwave-flash swf # Macromedia Shockwave file +application/x-spss sav spp sbs sps spo # SPSS +application/x-stuffit sit # Macintosh Stuff-It +application/x-sv4cpio sv4cpio # +application/x-sv4crc sv4crc # +application/x-tar tar # UNIX Tape Archive +application/x-tcl tcl # TCL Programming Language +application/x-tex tex # Tex/LaTeX +application/x-texinfo texinfo texi # TexInfo +application/x-troff t tr roff # Troff file +application/x-troff-man man # Troff with MAN macros +application/x-troff-me me # Troff with ME macros +application/x-troff-ms ms # Troff with MS macros +application/x-ustar ustar # Ustar file +application/vnd.ms-access mdb mda mde # MS Access +application/vnd.ms-project mpp # MS Project +application/x-wais-source src # WAIS Sources +application/zip zip jar # ZIP Compressed File +audio/basic au snd # Audio Sound File +audio/x-aiff aif aiff aifc # AIFF Sound File +audio/x-midi mid # MIDI Sound File +audio/x-pn-realaudio ra ram rm rpm # REALAUDIO Sound File +audio/x-wav wav # WAV Sound File +audio/x-mpegurl mp3 # MP3 Sound File +audio/mpeg3 mp3 # MP3 Sound File +audio/x-mpeg-3 mp3 # MP3 Sound File +audio/mpeg mp2 mpa mpg mpga # MP2 Sound File +audio/x-mpeg mp2 # MP2 Sound File +chemical/x-pdb pdb # PDB Chemistry Model File +chemical/x-xyz xyz # XYZ Chemistry Model File +drawing/x-dwf dwf # AutoCAD +image/gif gif # GIF image file +image/ief ief # Image Exchange +image/jpeg jpeg jpg jpe # JPG image file +image/png png # Portable Network Graphics +image/tiff tiff tif # TIFF image file +image/x-cmu-raster ras # +image/x-portable-anymap pnm # +image/x-portable-bitmap pbm # +image/x-portable-graymap pgm # +image/x-portable-pixmap ppm # +image/x-rgb rgb # RGB Image File +image/x-xbitmap xbm # X-bitmap Image File +image/x-xpixmap xpm # X-pixmap Image File +image/x-xwindowdump xwd # +text/css css # Cascading Style Sheet +text/html html htm # HTML Document +text/plain txt ini log in cfg m4 sh # Plain Text File +text/richtext rtx # Rich Text File +text/tab-separated-values tsv # +text/x-setext etx # +text/x-sgml sgml sgm # SGML Document +video/mpeg mpeg mpg mpe # MPEG Movie File +video/quicktime qt mov # Quicktime Movie File +video/x-ms-asf asf asx # Windows Media File +video/x-msvideo avi # AVI Movie File +video/x-sgi-movie movie # SGI Movie File diff --git a/src/jcifs/util/transport/Request.java b/src/jcifs/util/transport/Request.java new file mode 100644 index 0000000..892251f --- /dev/null +++ b/src/jcifs/util/transport/Request.java @@ -0,0 +1,4 @@ +package jcifs.util.transport; + +public interface Request { +} diff --git a/src/jcifs/util/transport/Response.java b/src/jcifs/util/transport/Response.java new file mode 100644 index 0000000..1a3be48 --- /dev/null +++ b/src/jcifs/util/transport/Response.java @@ -0,0 +1,6 @@ +package jcifs.util.transport; + +public abstract class Response { + public long expiration; + public boolean isReceived; +} diff --git a/src/jcifs/util/transport/Transport.java b/src/jcifs/util/transport/Transport.java new file mode 100644 index 0000000..aaeab42 --- /dev/null +++ b/src/jcifs/util/transport/Transport.java @@ -0,0 +1,263 @@ +package jcifs.util.transport; + +import java.io.*; +import java.net.*; +import java.util.*; +import jcifs.util.LogStream; + +/** + * This class simplifies communication for protocols that support + * multiplexing requests. It encapsulates a stream and some protocol + * knowledge (provided by a concrete subclass) so that connecting, + * disconnecting, sending, and receiving can be syncronized + * properly. Apparatus is provided to send and receive requests + * concurrently. + */ + +public abstract class Transport implements Runnable { + + static int id = 0; + static LogStream log = LogStream.getInstance(); + + public static int readn( InputStream in, + byte[] b, + int off, + int len ) throws IOException { + int i = 0, n = -5; + + while (i < len) { + n = in.read( b, off + i, len - i ); + if (n <= 0) { + break; + } + i += n; + } + + return i; + } + + /* state values + * 0 - not connected + * 1 - connecting + * 2 - run connected + * 3 - connected + * 4 - error + */ + int state = 0; + + String name = "Transport" + id++; + Thread thread; + TransportException te; + + protected HashMap response_map = new HashMap( 4 ); + + protected abstract void makeKey( Request request ) throws IOException; + protected abstract Request peekKey() throws IOException; + protected abstract void doSend( Request request ) throws IOException; + protected abstract void doRecv( Response response ) throws IOException; + protected abstract void doSkip() throws IOException; + + public synchronized void sendrecv( Request request, + Response response, + long timeout ) throws IOException { + makeKey( request ); + response.isReceived = false; + try { + response_map.put( request, response ); + doSend( request ); + response.expiration = System.currentTimeMillis() + timeout; + while (!response.isReceived) { + wait( timeout ); + timeout = response.expiration - System.currentTimeMillis(); + if (timeout <= 0) { + throw new TransportException( name + + " timedout waiting for response to " + + request ); + } + } + } catch( IOException ioe ) { + if (log.level > 2) + ioe.printStackTrace( log ); + try { + disconnect( true ); + } catch( IOException ioe2 ) { + ioe2.printStackTrace( log ); + } + throw ioe; + } catch( InterruptedException ie ) { + throw new TransportException( ie ); + } finally { + response_map.remove( request ); + } + } + private void loop() { + while( thread == Thread.currentThread() ) { + try { + Request key = peekKey(); + if (key == null) + throw new IOException( "end of stream" ); + synchronized (this) { + Response response = (Response)response_map.get( key ); + if (response == null) { + if (log.level >= 4) + log.println( "Invalid key, skipping message" ); + doSkip(); + } else { + doRecv( response ); + response.isReceived = true; + notifyAll(); + } + } + } catch( Exception ex ) { + String msg = ex.getMessage(); + boolean timeout = msg != null && msg.equals( "Read timed out" ); + /* If just a timeout, try to disconnect gracefully + */ + boolean hard = timeout == false; + + if (!timeout && log.level >= 3) + ex.printStackTrace( log ); + + try { + disconnect( hard ); + } catch( IOException ioe ) { + ioe.printStackTrace( log ); + } + } + } + } + + /* Build a connection. Only one thread will ever call this method at + * any one time. If this method throws an exception or the connect timeout + * expires an encapsulating TransportException will be thrown from connect + * and the transport will be in error. + */ + + protected abstract void doConnect() throws Exception; + + /* Tear down a connection. If the hard parameter is true, the diconnection + * procedure should not initiate or wait for any outstanding requests on + * this transport. + */ + + protected abstract void doDisconnect( boolean hard ) throws IOException; + + public synchronized void connect( long timeout ) throws TransportException { + try { + switch (state) { + case 0: + break; + case 3: + return; // already connected + case 4: + state = 0; + throw new TransportException( "Connection in error", te ); + default: + TransportException te = new TransportException( "Invalid state: " + state ); + state = 0; + throw te; + } + + state = 1; + te = null; + thread = new Thread( this, name ); + thread.setDaemon( true ); + + synchronized (thread) { + thread.start(); + thread.wait( timeout ); /* wait for doConnect */ + + switch (state) { + case 1: /* doConnect never returned */ + state = 0; + thread = null; + throw new TransportException( "Connection timeout" ); + case 2: + if (te != null) { /* doConnect throw Exception */ + state = 4; /* error */ + thread = null; + throw te; + } + state = 3; /* Success! */ + return; + } + } + } catch( InterruptedException ie ) { + state = 0; + thread = null; + throw new TransportException( ie ); + } finally { + /* This guarantees that we leave in a valid state + */ + if (state != 0 && state != 3 && state != 4) { + if (log.level >= 1) + log.println("Invalid state: " + state); + state = 0; + thread = null; + } + } + } + public synchronized void disconnect( boolean hard ) throws IOException { + switch (state) { + case 0: /* not connected - just return */ + return; + case 2: + hard = true; + case 3: /* connected - go ahead and disconnect */ + if (response_map.size() != 0 && !hard) { + break; /* outstanding requests */ + } + doDisconnect( hard ); + case 4: /* in error - reset the transport */ + thread = null; + state = 0; + break; + default: + if (log.level >= 1) + log.println("Invalid state: " + state); + thread = null; + state = 0; + break; + } + } + public void run() { + Thread run_thread = Thread.currentThread(); + Exception ex0 = null; + + try { + /* We cannot synchronize (run_thread) here or the caller's + * thread.wait( timeout ) cannot reaquire the lock and + * return which would render the timeout effectively useless. + */ + doConnect(); + } catch( Exception ex ) { + ex0 = ex; // Defer to below where we're locked + return; + } finally { + synchronized (run_thread) { + if (run_thread != thread) { + /* Thread no longer the one setup for this transport -- + * doConnect returned too late, just ignore. + */ + if (ex0 != null) { + ex0.printStackTrace(); + } + return; + } + if (ex0 != null) { + te = new TransportException( ex0 ); + } + state = 2; // run connected + run_thread.notify(); + } + } + + /* Proccess responses + */ + loop(); + } + + public String toString() { + return name; + } +} diff --git a/src/jcifs/util/transport/TransportException.java b/src/jcifs/util/transport/TransportException.java new file mode 100644 index 0000000..da65450 --- /dev/null +++ b/src/jcifs/util/transport/TransportException.java @@ -0,0 +1,38 @@ +package jcifs.util.transport; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +public class TransportException extends IOException { + + private Throwable rootCause; + + public TransportException() { + } + public TransportException( String msg ) { + super( msg ); + } + public TransportException( Throwable rootCause ) { + this.rootCause = rootCause; + } + public TransportException( String msg, Throwable rootCause ) { + super( msg ); + this.rootCause = rootCause; + } + + public Throwable getRootCause() { + return rootCause; + } + public String toString() { + if( rootCause != null ) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter( sw ); + rootCause.printStackTrace( pw ); + return super.toString() + "\n" + sw; + } else { + return super.toString(); + } + } +} +