Hacking JCIFS to support setting share permissions

For a recent project I was working on, I was required to set permissions on a remote windows share. All of the roads seemed to point to JCIFS as the library to do this. Unfortunately, JCIFS did not have support for the operations I required so I went about seeing what it would take to add them. This is the story of my JCIFS journey.

JCIFS is not what you might expect from a typical modern open source project. What source control system do they use? Git, SVN, Surely not CVS? I was surprised to find that the answer was none. There is no source control system that controls the official JCIFS releases. This stems from the fact that there is a single developer/maintainer of the codebase. The next thing I looked for was to see if I could find their bug tracking system. Same story. There is no bug tracking system for JCIFS either. The one thing JCIFS did have going for it was the active mailing list. Michael B Allen, the JCIFS developer/maintainer of the project, was very helpful in answering my questions to get me going.

What I Needed

What I was looking for was the ability to set Access Control on file shares of a Windows server. I found a promising patch that I thought was my answer on the JCIFS mailing list http://comments.gmane.org/gmane.network.samba.java/9045. It turns out that this was not exactly what I was looking for. This patch can be used to set file permissions (returned from JCIFS SmbFile.getSecurity()). What I was really looking for was to set permissions of the share (returned from JCIFS SmbFile.getShareSecurity()). This patch was a starting point but it would need some work.

If you have done any coding in Java that requires interoperability with Windows systems, you have probably come across JCIFS. JCIFS is an “Open Source client library that implements the CIFS/SMB networking protocol in 100% Java.” Many other java projects out there such J-Interop and many others use JCIFS internally. The reason for this is because JCIFS has implemented a Java version of Microsoft’s version of DCE/RPC. Leveraging this protocol, you can call pretty much any remote procedure call Microsoft has implemented. A great resource on what Microsoft has in this area is the MSDN documentation on Microsoft Communication Protocols (MCPP).

Microsoft has two protocols that I needed to add operations for:

  • [MS-SRVS]: Server Service Remote Protocol Specification
  • [MS-SAMR]: Security Account Manager (SAM) Remote Protocol Specification (Client-to-Server)

To SRVS, I needed to implement the NetrShareSetInfo call to set the permissions I was looking for. After working through this I realized I needed a way to lookup a user SID by name. To do this, I also implemented the SAMR call SamrLookupNamesInDomain.

Implementing My Changes

Implementing changes to the DCE/RPC calls in JCIFS was not trivial to figure out. There seemed to be generated code (srvsvc.java and samr.java) that was generated from srvsvc.idl and samr.idl. I figured Corba at first but quickly realized that this was not regular IDL. It was not even the Microsoft IDL as described in the Windows calls. This IDL was massaged into a format that JCIFS could work with. I spent a long time trying to find out how this IDL was compiled until I got a reply on the mailing list with this blog post by Christofer Dutz. He pointed out a tool that I missed called midlc that is part of JCIFS. It is unfortunately not referenced in the JCIFS main website at all other than having the download listed. Following his instructions, I was able to get midlc compiled and running.

The IDL compiler can be downloaded from http://jcifs.samba.org/src/midlc-0.6.1.tar.gz. It was originally built for Linux but compiles and runs fine on my mac. In a nutshell to compile it:

$ cd midlc-0.6.1/libmba-0.9.1
$ make ar
$ cd ..
$ make

Running the compiler was pretty simple as well.

./midlc -v -t jcifs -o [pathto]/srvsvc.java [pathto]/srvsvc.idl

Implementing the code to use this generated code was fun. There were a lot of good samples so it was not hard to get going.

Available for the future

I have made all of the work I did on JCIFS available on Github. Hopefully others will find it and use it.


Edit (March 30, 2012): Updated to include original setSecurity.patch I based my work on. This has since been removed from nabble.

4 thoughts on “Hacking JCIFS to support setting share permissions”

  1. Nice job. This is how people should contribute to JCIFS. You studied the right specs, wrote a little documentation about your mod and posted the whole package in a way that someone can pull down and use it without too much fuss (including me if I decide to add the NetShareSetInfo call to the stock JCIFS).

    Although your statement about the midlc IDL being different from midl IDL is not true at all. For example if you study at the SamrOpenDomain call from JCIFS’s samr.idl and the same IDL in the [MS-SAMR] document you site, you should find that they are actually the same IDL. It’s just the types that *look* different because Microsoft uses a lot of extraneous typedefs whereas JCIFS normalized a lot of common types. For example, JCIFS has a “policy_handle” type that is used all over the place in different RPC interfaces whereas Microsoft uses a different typedef in each interface for policy handles (SAMPR_HANDLE* in the case of samr). MS IDL is very much based on C (because with attributes removed it actually is C and MS embeds this stuff in their C files) so no doubt the typedefs would be confusing for someone who hasn’t used C much. To really see how the types are actually the same, you would have to trace back the typedefs to their origins. But usually you can tell just by the name or by looking at what JCIFS uses for some parameter that is the same in a different call.

  2. Chris, it is interesting to see that you have been stumbling across almost the same issue I have at hand for a customer project. In my case, however, I need to set the permissions on a single directory, so I was about to follow up on your approach with the path you mentioned (setSecurity on smbFile). However, this patch has been removed from the nabble.com website and I can’t seem to find it anywhere. Do you have a copy of it you could send me? I would love to enhance your patch to also include setSecurity().

  3. You are correct, the original patch does seem to be missing. The original patch had some issues with it. It had some formatting/whitespace changes in it making it difficult to apply without causing problems. I managed to take the pieces I needed.

    I will attach the original patch to my post so it is available to you.

Comments are closed.