[jcifs] Re: Accessing protected share from Servlet

David Webster dave_web at yahoo.com
Tue Jan 30 20:05:39 GMT 2007


Michael B Allen <mba2000 <at> ioplex.com> writes:

> 
> On Tue, 30 Jan 2007 15:05:04 +0000 (UTC)
> David Webster <dave_web <at> yahoo.com> wrote:
> 
> > I am a newb to jcifs and have been looking over the doc and examples for 
the 
> > last couple days, but I haven't been able to put together a solution that 
> > entirely fits my needs:
> > 
> > 1) NTLM via the HttpFilter. (This works)
> > 
> > 2) Presentation of files contained in a share with permissions based off 
of 
> > the NTLM authentication created during the HttpFilter authentication.
> > 
> > 
> > I cannot figure out how to apply the permissions verified by the filter to 
the 
> > file share itself.
> > 
> > The constructor for SmbFile takes either a filePath or a filePath and 
> > NtlmPasswordAuthentication. Just using the filePath doesn't work.
> > 
> > Do I need to renegotiate every request outside of the HttpFilter?
> > 
> > I hope I am missing something really simple.
> 
> It's not. You must renegotiate for each server you talk to. See
> jcifs/http/NetworkExplorer.java.
> 
> Mike
> 


OK I have chopped apart the code of NetworkExplorer to the following method:


Please no coding standard remarks, I am just trying to get this to work :)


public NtlmPasswordAuthentication authenticate( HttpServletRequest req, 
HttpServletResponse resp)
        throws UnknownHostException, SmbException, IOException, 
ServletException{

        boolean credentialsSupplied = false;
        boolean enableBasic = false;
        boolean insecureBasic = false;
        String realm = null;
        String defaultDomain = Config.getProperty("jcifs.smb.client.domain");

        UniAddress dc;
        String msg = null;
  
        String server = "shareservername";
        boolean offerBasic, possibleWorkgroup = true;
        NtlmPasswordAuthentication ntlm = null;
        HttpSession ssn = req.getSession( false );

       //Begin Authorization
       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;
                System.out.println( "Message is NTLM " );
                //if( pathInfo == null || server == null ) {
                //    String mb = NbtAddress.getByName( 
NbtAddress.MASTER_BROWSER_NAME, 0x01, null ).getHostAddress();
                //    System.out.println( "mb " + mb );
                //    dc = UniAddress.getByName( mb );
                //} else {

                    dc = UniAddress.getByName( server, possibleWorkgroup );
                    System.out.println( "dc " + dc );

                //}

                req.getSession(); // ensure session id is set for cluster env. 
                challenge = SmbSession.getChallenge( dc );
                System.out.println( "challenge " +  new String( challenge ) );
                ntlm = NtlmSsp.authenticate( req, resp, challenge );

            } else { // Basic 

                System.out.println( "Message is 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);
            }

            System.out.println( "Setting session npa-" + server + " = " +  
ntlm );
            req.getSession().setAttribute( "npa-" + server, ntlm );

        } else if( !credentialsSupplied ) {
            System.out.println( "No Credentials Supplied " );
            if( ssn != null ) {
                System.out.println( "Using stored ntlm: " +"npa-" + server );
                ntlm = (NtlmPasswordAuthentication)ssn.getAttribute( "npa-" + 
server );
            }
            if( ntlm == null ) {
                System.out.println( "Requesting Authentication " );
                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();
            }
        }

        System.out.println( "Returning " + ntlm );
        return ntlm;
    }


Note the commented out section under (if msg starts with NTLM) I get a 
java.net.UnknownHostException: ..__MSBROWSE__.<01> When that is uncommented. 

With the code as it is, I get the apparently common 
jcifs.smb.SmbAuthException: Invalid access to memory location.

It seems that I am still not authenticating against the correct server shown 
by the "server" variable above. If it isn't the server that the share resides 
on and it isn't the domain controller. What is it?

The sever name is a cluster name, that probably has some impact, but I have 
tried the cluster name and an actual server name and both fail.




More information about the jcifs mailing list