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.useExtendedSecurity | True 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 `SmbFile`s 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.