x
Loading
 Loading
Featured Paper: Xen Virtualization with Novell SUSE Linux
Hello, Guest | Login | Register

jCIFS: The SMB Can Opener

The tale of jCIFS is a Romeo and Juliet story: two technologies find each other on the Internet and come together despite a feud between their parents. Only this time, there’s a happy ending.

Community Tools
RSS
Recommend This [?]
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...
Users That Liked This [?]
No one yet. Be the first.
Tags:
Tag This!
 No Comments

jCIFS (http://jcifs.samba.org/) is the product of an unlikely union between Sun’s Java and Microsoft’s SMB/CIFS file sharing suite. jCIFS provides all of the tools a Java coder needs to get along in a Windows Network Neighborhood; jCIFS dances elegantly with Samba; and jCIFS runs on everything from palmtops to mainframes. Where else but in open source could such a story be told?

Romance, drama, intrigue, pathos, and protocols. Shakespeare, move over.

SMB is the Server Message Block protocol. It was created at IBM back in the mid-’80s as a way of letting DOS personal computers share files with one another. In the early days, IBM collaborated with Microsoft and a few other companies on the development of SMB, which became a standard part of both OS/2 and Microsoft Windows. Since then, several third-party implementations were also written, and today the best-known of those is Samba, an open source SMB server suite first introduced in 1992.

Microsoft eventually took over control of SMB development, and, in the mid-’90s, they gave it a “marketing upgrade.” Microsoft renamed it the Common Internet File System, or CIFS, gussied it up a little, and trotted it out as a worthy competitor to Sun’s WebNFS.

The nineties were the heady days of the Internet, when establishing a new protocol as a de facto standard was seen as equivalent to staking a claim on a gold mine. Sun had already proposed WebNFS (basically a web-enabled version of NFS) as an Internet file sharing standard. Microsoft apparently felt the urge to compete.

WebNFS was an open protocol with published specifications. Microsoft had hopes that they could build support for their candidate by opening it up a little bit too, so they produced some IETF Internet Drafts to give outsiders a peek at the protocol innards — a big help to third-party implementers, such as the Samba Team. As things turned out, however, neither CIFS nor WebNFS ever really caught on as the universal standard for Internet file sharing, and Microsoft has since become more and more secretive about the workings of CIFS.

These days, most folks in the CIFS community use the name “SMB” when they want to talk about the core file sharing protocol, and “CIFS” when they want to talk about the suite as a whole. The distinction is useful because several sub-protocols have been created over the years to make SMB services more flexible and easier to manage. There are, for example, sub-protocols for name resolution, remote server management, and for organizing and presenting the Network Neighborhood. Each of these are intertwined with SMB in different ways.

To Windows users, CIFS typically looks something like Figure One. In older versions of Windows, this was called the “Network Neighborhood,” but newer Windows flavors call it “My Network Places” or “Computers Near Me.” No matter. It’s just a graphical view of the available CIFS file services, arranged into categories known as workgroups or domains.

FIGURE ONE: The Windows “Network Neighborhood”



Despite it’s proprietary nature, CIFS filesharing is annoyingly pervasive. Starting with Windows for Workgroups, every Microsoft operating system has come with CIFS built in, making it a brute-force standard. In recent years, Linux, FreeBSD, MacOS X, and even AmigaOS have all gained CIFS client file systems (the ability to use a remote directory as if it were a local disk). Samba provides the server side of the equation for non-Microsoft platforms, so CIFS winds up having almost universal support. As a result, CIFS is an exceptionally convenient mechanism for sharing files and directories on local networks.

Things are a bit different on the wide open Internet, however. As noted earlier, CIFS never really caught on as a long-haul carrier. In part, that’s because IBM originally designed SMB to run on small private LANs and, despite Microsoft’s efforts, it has some trouble scaling to larger, more complex environments. It is particularly prone to problems caused by the higher latency on long-distance links (though there are several companies now working on intriguing solutions to this problem). Another factor is that it’s considered a major security risk to expose CIFS servers to the Internet. As you shall soon see, jCIFS offers a nifty work-around for the security problem.

jCIFS: Your All-Purpose CIFS Client Toolkit

jCIFS implements all of the key elements of the CIFS suite, making it easy to build your own Java-powered Network Neighborhood browser, file transfer utility, or authentication widget. However, jCIFS is a client toolkit only. It is not intended to replace Windows or Samba as a CIFS server.

Although it’s designed to be a client, there is one trick that jCIFS can do that blurs the distinction between client and server: jCIFS can be used in conjunction with a web server to provide proxy access to CIFS resources on remote networks. This can be really useful if you want to make files available while protecting your CIFS servers from exposure.

Figure Two shows an example configuration that provides a jCIFS-powered web interface to a CIFS filesharing network. The CIFS server is on an internal LAN — an intranet — protected from the big bad Internet by a firewall. The web servers are in the firewall’s DMZ, semi-protected and separate from the internal network. They have access through the firewall to the SMB/CIFS services, but still have to provide authentication to get there.

jCIFS acts as the go-between. A Java servlet converts web requests into SMB file and directory access requests and forwards those to the CIFS server. It then takes the responses from the CIFS server, and converts them to HTML format to be sent back to the client.

FIGURE TWO: jCIFS provides web proxy access to the Network Neighborhood



To make this work, jCIFS must also handle a variety of authentication mechanisms. The CIFS suite has its own special logon protocols, and jCIFS can deal with most of them. NTLMv2 and Microsoft Kerberos are the current exceptions (though a subset of NTLMv2, known as LMv2, is supported).

As you would expect, once authenticated a user can view the workgroups and servers in the Network Neighborhood, can browse through shares and directories, and can download files. Access is read-only, however, which is fine in many cases. If the situation calls for read/write access… Well, there’s a way to handle that, too.

Getting Started with jCIFS

If you’d like to work with jCIFS, the first thing you’ll need is the JAR file. (JAR files are compressed Java bytecode libraries, so jcifs.jar is basically all of jCIFS compiled and squished into a small container using the venerable ZIP algorithm.) You can find the jCIFS JAR at http://jcifs.samba.org.

Once downloaded, simply place jcifs.jar somewhere on your CLASSPATH so Java can find it. The JAR file is the only thing that you actually need to copy to your system in order to use jCIFS. Everything else is a bonus.

Next, you will probably want the jCIFS API Docs found at http://jcifs.samba.org/src/docs/api/. These are written in JavaDoc and are included if you download the entire jCIFS distribution, but it’s simpler to browse the online copy available on the jCIFS website.

jCIFS also comes with a whole bunch of example programs, running the gamut from simple to inscrutable. Some are intended to jumpstart beginners, while others are used to push jCIFS or a target server to its limits. Some of them may also be a little out of date, so pay attention to the code. (Let it be a learning experience.)

All of the jCIFS source, including the examples, can be viewed online at the jCIFS website. Just follow the download link at http://jcifs.samba.org/src/. The examples are in examples/.

The most useful classes in jCIFS are modeled after familiar Java classes, so Java programmers should have little trouble getting up to speed. The jcifs.smb.SmbFile class, for instance, behaves a lot like java.io.File. Similarly, SmbFileInputStream and SmbFileOutputStream are analogous to FileInputStream and FileOutputStream, respectively.

Listing One provides a simple example program called Ls.java that demonstrates how the jcifs.smb.SmbFile class is used. The program displays a directory listing from a remote CIFS server. It’s a concise bit of code because all of the busywork is being done by jCIFS.

LISTING ONE: Ls.java lists CIFS shares, directories, and files

import jcifs.smb.SmbFile;

public class Ls {

public static void main(String[] argv) throws Exception {
SmbFile file = new SmbFile(argv[0]);
String[] files = file.list();

for (int i = 0; i < files.length; i++) {
System.out.println( files[i] );
}

System.out.println( “[” + files.length + ” files]” );
}
}

The program starts off by creating an SmbFile object. It passes in a user-specified SMB pathname (via argv[0]) as input to the constructor. The user’s input identifies the server and, optionally, the directory path to be listed. The SmbFile instance represents the connection to the remote SMB resources.

The next step is to call the SmbFile.list() method, which gathers the directory listing from the remote server. The list is subsequently printed, and that’s all there is to it.

The critical part here is the user input. jCIFS needs to know the server, share, and pathname to make a connection. For this particular program, that’s all specified on the command line using the SMB URI format. Yes, there really is a URI format for SMB/CIFS.

When jCIFS was being developed, it became apparent that a consistent mechanism for identifying CIFS resources was needed. Forutately, the SMB URI scheme was being developed at the same time (by some of the same people). It was a natural fit, and the SMB URI became the centerpiece of all jCIFS operations.

The SMB URI

If you’ve ever tried to get a wet cat to hold still for a tuxedo fitting, you’ll have some idea what it was like to create a URI scheme for the SMB/CIFS suite. Ouch.

It wasn’t very difficult to figure out how to make the basic stuff work. The yowling and rending of flesh started when it came time to add Windows Domain authentication and Network Neighborhood browsing support. These “extras” made it necessary to pull, stretch, twist, and squeeze the standard URI syntax to get it to cover everything decently.

The syntax of the SMB URI scheme wound up looking something like this:

smb://[[[ authdomain;] user@] host[: port] /[ share/[ path/][ file]]][? context]

The stuff in brackets is optional, of course, and there are a lot of brackets. That means that there’s a lot of potential variety in the formation of SMB URIs. jCIFS, however, is driven by this stuff so it’s very important to get an understanding of how it works. Hang on for a few paragraphs… We’ll try to make sense of it all.

For simple things, the SMB URI behaves pretty much as you’d expect: it allows you to connect to a server and move up and down within the directory hierarchy. CIFS servers can be identified by DNS name or IP address just like any other URI scheme, but the SMB scheme also accepts old-fashioned NetBIOS names. These are a throw-back to the early days of SMB, before the world standardized on TCP/IP. Remnants of the old NetBIOS system still linger in Windows, like ghosts in a haunted house.

Two such remnants — Workgroups and NT Domains — were mentioned earlier. They provide a way to gather servers into categories so that they’re easier to find. From the perspective of the Network Neighborhood, there is no difference between a Workgroup and an NT Domain. They really are the same thing. Promise.

Figure Three shows how a list of Workgroups is presented by Windows. In this example, only two are available: Filbert and Ubiqx. An enterprise-class network would likely have many more.

FIGURE THREE: A Windows view of the “Entire Network”



Workgroups are handled by the SMB URI using smb:// or smb://workgroup/. The first form, smb://, is used to request the list of available workgroups — the” Entire Network” in Figure Three. The second form is used to get a list of servers that are members of the specified workgroup. There is one small problem with that second form. It is syntactically identical to smb://fileserver/. So, how do we tell the two apart?

This is one of the annoyances of the SMB URI. Fileservers and workgroups can only be distinguished semantically, that is, by resolving the name and querying the server to see what kinds of services it is offering. You can’t just look at the URI and know what it means, you have to go to the wire. jCIFS does this by sending queries in parallel, which speeds things up a bit.

Authentic SMB URIs

Now let’s roll up our sleeves and get our hands dirty by adding authentication to the mix.

A lot of URI schemes allow the user to include a username and, sometimes, a password.([ Ed.: Put a link to the warning sidebar here?]) The SMB URI goes one step further and provides support for something called an authentication domain. So, what’s an authentication domain?

A few paragraphs back we said that workgroups and NT domains were the same thing. That was a lie… but just a tiny one. The only real difference is that NT domains have one or more Domain Controllers providing authentication services. Other than that, they really truly are the same thing. Promise.

The SMB URI includes support for NT domain authentication. Just add the NetBIOS domain name ahead of the username, separated by a semicolon:

smb://authdomain;username:password@fileserver/

(There was a bit of hand wringing and teeth gnashing when the semicolon was chosen as the delimiter. Unfortunately, URIs are complex beasts and the semicolon was one of the few characters that were still available.)

One more note about the URI syntax. At the tail end there’s something called the ?context, which is intended to handle some of those pesky NetBIOS remnants that were mentioned earlier. This is a relatively recent addition to the SMB URI, and jCIFS doesn’t support it yet.

The SMB URI scheme is working its way through the IETF’s Internet Draft process. By the time this article appears in print, the current version, draft-crhertel-smb-url-07, will be replaced by a newer version. To find the latest update, scan through the IETF’s Internet Drafts directory at http://www.ietf.org/internet-drafts/.

Déjŕ Va

It’s time to revisit the example program in Listing One. If you have Java installed, your CLASSPATH set correctly, and a CIFS server to test against, then all of the pieces are in place. Let’s give it a test run:

$ javac Ls.java
$ java Ls smb://omega/D/
BOOTLOG.TXT
COMMAND.COM
SUHDLOG.DAT
FRUNLOG.TXT
MSDOS.—
SETUPLOG.TXT
WINDOWS
NETLOG.TXT
MSDOS.SYS
:
:

Chances are, it won’t be that simple. This is, after all, the CIFS suite we are dealing with. There are a good number of little quirks that you’ll have to work out. The most likely problem you’ll encounter will look something like this:

Exception in thread “main” jcifs.smb.SmbAuthException: Logon failure:
unknown user name or bad password.
at jcifs.smb.SmbTransport.send(SmbTransport.java:695)
at jcifs.smb.SmbSession.sessionSetup(SmbSession.java:271)
at jcifs.smb.SmbSession.send(SmbSession.java:228)
at jcifs.smb.SmbTree.treeConnect(SmbTree.java:134)
at jcifs.smb.SmbFile.connect(SmbFile.java:826)
at jcifs.smb.SmbFile.connect0(SmbFile.java:796)
at jcifs.smb.SmbFile.sendTransaction(SmbFile.java:658)
at jcifs.smb.SmbFile.doFindFirstNext(SmbFile.java:1698)
at jcifs.smb.SmbFile.list(SmbFile.java:1563)
at jcifs.smb.SmbFile.list(SmbFile.java:1455)
at Ls.main(Ls.java:7)

This is an authentication failure. (See where it says unknown user name or bad password?) It’s easy to fix, if you have a username and password on the server. Just change the URI string to include your credentials:

$ java Ls smb://crh:pazzWoid@omega/D/
BOOTLOG.TXT
COMMAND.COM
SUHDLOG.DAT
:
:

Like magic, with the correct username and password, access is granted.

Another common problem is being unable to find the server:

$ java Ls smb://Frelbstat/c/
Exception in thread “main” jcifs.smb.SmbException:
Failed to connect to server
java.net.UnknownHostException: Frelbstat

This is typically caused by forgetting to set the IP address of your WINS server. The WINS server is really a NetBIOS Name Server (NBNS) and, as you’ve already guessed, it’s another one of those NetBIOS throw-back thingies. It’s job is to map NetBIOS names to IP addresses. Here’s how to set the address of the WINS server:

$ java –Djcifs.netbios.wins=192.168.101.1 Ls smb://Frelbstat/c/
BOOTLOG.TXT
FRUNLOG.TXT
DETLOG.TXT
COMMAND.COM
:
:

The string jcifs.netbios.wins that you see on the command line is a property. Java properties are sort of like environmental variables or configuration options that you set at run-time to give the application some clues as to how it should behave. jCIFS has a list of available properties, all of which are described in the documentation.

You can set properties individually using the –D command line option, or place them into a properties file, like so:

$ cat crh.prp
jcifs.smb.client.username = crh
jcifs.netbios.wins = 192.168.101.1
jcifs.netbios.baddr = 192.168.101.255

$ java –Djcifs.properties=crh.prp Ls smb://Frelbstat/c/
BOOTLOG.TXT
FRUNLOG.TXT
DETLOG.TXT
COMMAND.COM
:
:

Setting the properties correctly before you start working with jCIFS saves a lot of headaches. Otherwise, you might bang your head against the keyboard forcefully, which will cause a lot of headaches. Decisions, decisions…

Where Two?

jCIFS is accelerating. It took five years of development before it reached version 1.0.0. That happened last September, but the 1.x.x branch is already considered to be stable–only critical bugfixes are being made–and there are plans for jCIFS 2.0.0.

In the mean time, Mike has created an Interface Definition Language (IDL) compiler that produces Java stubs that can be use with another jCIFS spinoff called Jarapac–a DCE/RPC engine for Java that can interoperate with Microsoft services via Remote Procedure Call. This is a very powerful capability as all of the descendents of Windows NT make heavy use of RPC.

There is also a lot of arguing that still goes on surrounding the definition and implementation of the SMB URI. Most of that discussion occurs on the jCIFS list in part because the SMB URI is so central to the operation of jCIFS and in part because the jCIFS community really cares about getting things right.

All of this from a wisp of inspiration, a vague sense of direction, and the star-crossed story of two technologies that met on the Internet.

Free Email Newsletters
Linux Mag Weekly
Blade & Virtualization
Making the Most of Multicore
HPC Weekly
Linux Magazine Case Study Update
Linux Magazine Webinar Update
Linux Magazine White Paper Update
Linux Magazine PR Daily
Email Address:

ActivSupport
Linux Magazine has chosen ActivSupport as IT consultants.
Sponsored Links