NullpointerException when creating new SmbFileInput

953 views Asked by At

I have a java web application, which needs to read a file from a network drive. It works perfectly when i run it on a localhost test server, as I am logged in with my windows credentials. It does not however work when deployed on a company server.

I have been trying to implement a way to send user credentials along when trying to access the file, and my current attempt is using The Java CIFS Client Library

I am basing my attempts on the code in this answer, although my code needs to read from a file instead of write to one. I am getting a NullpointerException I cannot explain.

Code:

public static void main(String[] args) {

    String filePath = "[myPath]";
    String USER = "domain;username:password";

    try {

        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(USER);
        SmbFile sFile = new SmbFile(filePath, auth);        
        if(sFile.exists()){
            InputStream stream = new SmbFileInputStream(sFile); //throws exception
        }

    } catch (SmbException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Error:

Exception in thread "main" java.lang.NullPointerException
    at jcifs.smb.ServerMessageBlock.writeString(ServerMessageBlock.java:213)
    at jcifs.smb.ServerMessageBlock.writeString(ServerMessageBlock.java:202)
    at jcifs.smb.SmbComNTCreateAndX.writeBytesWireFormat(SmbComNTCreateAndX.java:170)
    at jcifs.smb.AndXServerMessageBlock.writeAndXWireFormat(AndXServerMessageBlock.java:101)
    at jcifs.smb.AndXServerMessageBlock.encode(AndXServerMessageBlock.java:65)
    at jcifs.smb.SmbTransport.doSend(SmbTransport.java:439)
    at jcifs.util.transport.Transport.sendrecv(Transport.java:67)
    at jcifs.smb.SmbTransport.send(SmbTransport.java:655)
    at jcifs.smb.SmbSession.send(SmbSession.java:238)
    at jcifs.smb.SmbTree.send(SmbTree.java:119)
    at jcifs.smb.SmbFile.send(SmbFile.java:775)
    at jcifs.smb.SmbFile.open0(SmbFile.java:989)
    at jcifs.smb.SmbFile.open(SmbFile.java:1006)
    at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:73)
    at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:65)
    at Test.main(Test.java:45)

The user credentials are accepted. I've tried both valid and invalid credentials, and the invalid ones gives user identification errors.

The exception is thrown when creating the inputstream, which normally would make me think that the parameter sFile object, would be null, or have a null field. I do not know which field this might be. Debugging shows that isExists = true. The URL is also valid. Here is a screenshot of my sFile object from the debugger:

enter image description here

What am i missing here? Why do i get a nullpointerexception?

1

There are 1 answers

0
jumps4fun On BEST ANSWER

After traversing the source code, I found that the unc variable was the one causing the NullPointerException. Long story short, my struggle was caused by me not following the standard url pattern of smb, and the jcifs library failing to give me information about this. The rules can be found here (right after the initial import statements). Here is a selection:

SMB URL Examples

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.