[jcifs] [patch] Resolve SIDs in ACE[]s from getSecurity() to Human Readable Names

Michael B Allen mba2000 at ioplex.com
Wed Apr 5 01:22:47 GMT 2006


No. This is something that needs a little work.

First, there really needs to be some code to find the right host to query
for resolving SIDs. Querying the server of the target object as shown
in the code below is not correct (although it might work). There needs
to be a lookup that indicates the correct host for resolving a specific
SID. As I'm sure you know by now a SID is composed of a domain part and
and a relative identifier:

       SID: S-1-5-21-12345-23456-34567-1122
Domain SID: S-1-5-21-12345-23456-34567
       RID: 1122

So you need to lookup the domain/machine name that maps to the domain SID
S-1-5-21-12345-23456-34567. Then you do a NetBIOS lookup (or preferrably
an SRV DNS query) to determine the IP (possibly via DNS hostname) of
a specific server for the target name. Then you do an LSA bind with
that server and perform the LsarLookupSids call to resolve one or more
sids that begin with the target domain SID. I'm not certain that all of
these steps are necessary. It could be that any local domain controller
will recursively query other domain controllers on your behalf but
that would require some experimentation. If I were doing this I would
most certainly obtain packet captures of a Windows client peforming
the desired operations (e.g. write a small Win32 program that models
your application). Then I could know definitively how the Java side
should behave.

Second, there needs to be a SID cache. Without a SID cache the
domain controller could become overloaded with requests to resolve
SIDs (depending on the application of course). SIDs NEVER change so
they can be heavily cached. So the interface should be adjusted a
little. Specifically, add hashCode() and equals() methods to the SID
class. Add a 'state' member to the SID class with possible states
ST_GROUND, ST_RESOLVING, ST_FAILED, and ST_RESOLVED. Also add a
'name' member to hold the result of the name corresponding to the sid
(e.g. 'FOONET\Domain Admins', 'FOONET\tbley', 'BARNET\Backup Operator',
etc). Now when a SID needs to be resolved you query a hash map (the
SID cache). If the SID is found, check the state - if the state is
ST_RESOLVED, return success - if the state is ST_FAILED, return failure
- if the state is ST_RESOLVING, call wait() on the map. If the SID is
NOT found in the map, set the state of the callers SID to ST_RESOLVING,
insert it into the map, and proceed to resolve it using the said technique
of looking up the correct domain, doing the LsarLookupSids call and so
on. When resolved, set the state to ST_RESOLVED or ST_FAILED and notify()
on the map. This is all off-the-top-of-my-head of course.

In general, the patch is not optimal for resolving arbitrary SIDs
because it doesn't provide any facility to locate the correct LSA
database. However, if you're certain that the SIDs will all be in the
same domain (usually are) or after some experimentation you find that
a target machine will recursively query other domains to some degree
then it may be possible to simply use "new LsaRPC(<domainController>)"
where domainController is the IP of a local domain controller (or in
your case a workstation IP). For example, in the case of the NTLM HTTP
Filter this simplified technique might be suffecient (although a cache
is STRONGLY recommended for the Filter).

Anyway I suppose I've only dug a deeper hole than the one you're
in. The short answer is to pass the SmbFile.auth member to the LsaRPC
constructor or lookupSids() call so that they can in turn pass the NPA
to the SmbNamePipe constructor (wherever that is - I don't recall).

You should realize that querying individual hosts for SID names is
unusual. In a MS client's natural habitat it would query the domain
controller(s) directly (and probably cache the results).

Mike

On Thu, 06 Apr 2006 00:03:00 +0200
Thomas Bley <thomas.bley at simple-groupware.de> wrote:

> Hello,
> 
> Thanks a lot, can I pass over the NtlmPasswordAuthentication object from 
> jCIFS to Jarapac ?
> The rpc-call is done directly from SmbFile.java:
> 
>    public ACE[] getSecurity() throws IOException {
>         int f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 );
> 
>         /*
>          * NtTrans Query Security Desc Request / Response
>          */
>         NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( 
> f, 0x04 );
>         NtTransQuerySecurityDescResponse response = new 
> NtTransQuerySecurityDescResponse();
>         send( request, response );
> 
>         LsaRPC lsa = new LsaRPC(getServer());
>         try {
>             lsa.lookupSids(response.aces);
>         } catch(IOException e) {
>             throw new SmbException("Unable to resolve SIDs",e);
>         } finally {
>             close( f, 0L );
>         }
>         return response.aces;
>     }
> 
> Best regards,
> Thomas Bley
> 
> 
> Michael B Allen wrote:
> > The pipe to IPC$ needs to use valid creds for the DC. So if you don't
> > supply jcifs.smb.client.{domain,username,password} then GUEST is tried
> > (which will almost invariably fail). Whenever I run examples (from
> > Jarapac or jcifs) I use a properties file in a parent directory that
> > has my credentials and then use java -Djcifs.properties=../miallen.prp
> > ListAcl ...
> >
> >
> > On Tue, 4 Apr 2006 13:32:39 +0200
> > "Martin D. Pedersen" <mdp at visanti.com> wrote:
> >
> >   
> >>  Hi Thomas
> >>
> >> I think you are right ... It seems to use the Guest Account.
> >> I've had some problems with TransactNamedPipeOutputStream and I think I
> >> might have "forced" it to that behavior.
> >>
> >> I will have a look at it and see if I can fix it.
> >>
> >> -- Martin
> >>
> >>
> >>
> >>     
> >>> -----Original Message-----
> >>> From: Thomas Bley [mailto:thbley at gmail.com] On Behalf Of Thomas Bley
> >>> Sent: 4. april 2006 01:55
> >>> To: mba2000 at ioplex.com
> >>> Cc: jcifs at samba.org; Martin D. Pedersen
> >>> Subject: Re: [jcifs] [patch] Resolve SIDs in ACE[]s from 
> >>> getSecurity() to Human Readable Names
> >>>
> >>> Hello,
> >>>
> >>> Looks like the rpc uses the guest account, I enabled the 
> >>> guest account on my machine and got this:
> >>> Logon failure: the user has not been granted the requested 
> >>> logon type at this computer.
> >>>
> >>> Next I changed my "Local security settings":
> >>> - removed Guest from "Deny logon locally"
> >>> - removed Guest from "Deny access to this computer from the network"
> >>> and it seems to work.
> >>>
> >>> My args[0] is:
> >>> smb://administrator:xxx@192.168.0.2/temp/Test/
> >>>
> >>> So I think I need to set the credentials somewhere ?
> >>> Also I get all rpc dumps, do I missed to set a logLevel somewhere ?
> >>>
> >>> Best regards,
> >>> Thomas
> >>>
> >>>
> >>> Thomas Bley wrote:
> >>>       
> >>>> Hello,
> >>>>
> >>>> I tried the resolve patch with my WinXP (SP2) as Server, 
> >>>>         
> >>> but no success:
> >>>       
> >>>> I get the listing from a folder and the ACEs, but I can't 
> >>>>         
> >>> resolve SIDs.
> >>>       
> >>>> The patch modifies TransactNamedPipeOutputStream.java, do I 
> >>>>         
> >>> also need 
> >>>       
> >>>> to modify TransactNamedPipeInputStream.java ?
> >>>> Or is there anything else wrong ?
> >>>>
> >>>> I have:
> >>>>    public static void main( String[] args ) throws Exception {
> >>>>        if (args.length < 1) {
> >>>>            System.err.println( "usage: ListACL <smburl>\n" );
> >>>>        }
> >>>>        SmbFile f = new SmbFile( args[0] );
> >>>>              String[] files = f.list();
> >>>>        for( int i = 0; i < files.length; i++ ) {
> >>>>            System.out.print( " " + files[i] );
> >>>>        }
> >>>>        System.out.println();
> >>>>              ACE[] acl = f.getSecurity();
> >>>>        for (int i = 0; i < acl.length; i++) {
> >>>>            System.out.println( acl[i] );
> >>>>        }
> >>>>    }
> >>>>
> >>>>
> >>>> The output is:
> >>>> serial.txt Test
> >>>> jcifs.smb.SmbException: Unable to resolve SIDs
> >>>> jcifs.smb.SmbAuthException: Logon failure: account 
> >>>>         
> >>> currently disabled.
> >>>       
> >>>>    at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:499)
> >>>>    at jcifs.smb.SmbTransport.send(SmbTransport.java:610)
> >>>>    at jcifs.smb.SmbSession.sessionSetup(SmbSession.java:268)
> >>>>    at jcifs.smb.SmbSession.send(SmbSession.java:225)
> >>>>    at jcifs.smb.SmbTree.treeConnect(SmbTree.java:147)
> >>>>    at jcifs.smb.SmbFile.connect(SmbFile.java:796)
> >>>>    at jcifs.smb.SmbFile.connect0(SmbFile.java:766)
> >>>>    at 
> >>>>         
> >>> jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:72)
> >>>       
> >>>>    at
> >>>>
> >>>>         
> >>> jcifs.smb.TransactNamedPipeInputStream.<init>(TransactNamedPipeInputSt
> >>>       
> >>>> ream.java:38)
> >>>>
> >>>>    at
> >>>>
> >>>>         
> >>> jcifs.smb.SmbNamedPipe.getNamedPipeInputStream(SmbNamedPipe.java:166)
> >>>       
> >>>>    at jcifs.smb.RpcTransport.attach(RpcTransport.java:91)
> >>>>    at rpc.Stub.attach(Stub.java:105)
> >>>>    at rpc.Stub.call(Stub.java:110)
> >>>>    at jcifs.rpc.LsaRPC.openPolicy(LsaRPC.java:62)
> >>>>    at jcifs.rpc.LsaRPC.lookupSids(LsaRPC.java:94)
> >>>>    at jcifs.smb.SmbFile.getSecurity(SmbFile.java:2564)
> >>>>    at ListACL.main(ListACL.java:17)
> >>>>
> >>>>    at jcifs.smb.SmbFile.getSecurity(SmbFile.java:2566)
> >>>>    at ListACL.main(ListACL.java:17)
> >>>> Exception in thread "main"
> >>>>
> >>>>
> >>>> Without "lsa.lookupSids(response.aces);" I get:
> >>>>
> >>>> serial.txt Test
> >>>> inherited allow 0x001F01FF 
> >>>> S-1-5-21-842925246-1060284298-1708537768-1003
> >>>> inherited allow 0x001F01FF S-1-1-0
> >>>> inherited allow 0x001200A9 
> >>>> S-1-5-21-842925246-1060284298-1708537768-501
> >>>>
> >>>>
> >>>> Thanks and best regards,
> >>>> Thomas
> >>>>
> >>>>
> >>>> Michael B Allen wrote:
> >>>>         
> >>>>> Nice Job Martin.
> >>>>>
> >>>>> The UnicodeString type from Jarapac that extends 
> >>>>>           
> >>> rpc.unicode_string 
> >>>       
> >>>>> should be used although it would need some fixing up (e.g. replace 
> >>>>> the toString contents with that of your uniCodeToString method).
> >>>>> Also, jcifs.smb.SID should be modified to extend rpc.sid_t to take 
> >>>>> advantage of polymorphic behavior there also. Then you can 
> >>>>>           
> >>> use those 
> >>>       
> >>>>> extended types wherever you would use rpc.unicode_string or 
> >>>>> rpc.sid_t. That would simplify and speed things up a little.
> >>>>>
> >>>>> It should be noted that users will need the Jarapac jar file:
> >>>>>
> >>>>>   http://sourceforge.net/projects/jarapac/
> >>>>>
> >>>>> Note: the Jarapac CVS repo is severly broken. Always download the 
> >>>>> package.
> >>>>>
> >>>>> The patch is in the patches directory:
> >>>>>
> >>>>>   http://jcifs.samba.org/src/patches/
> >>>>>
> >>>>> It will be interesting to see how this works for people.
> >>>>>
> >>>>> Mike
> >>>>>
> >>>>> On Wed, 29 Mar 2006 10:01:45 +0200
> >>>>> "Martin D. Pedersen" <mdp at visanti.com> wrote:
> >>>>>
> >>>>>  
> >>>>>           
> >>>>>> Hi Michael
> >>>>>>
> >>>>>>     
> >>>>>>             
> >>>>> <snip>
> >>>>>  
> >>>>>           
> >>>>>> It works just fine.
> >>>>>>
> >>>>>> I have included a new SID resolve patch.
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> Best regards   Martin Pedersen
> >>>>>>     
> >>>>>>             
> >>>>>   
> >>>>>           
> >>>>         
> >>>
> >>>       
> >
> >
> >   
> 


More information about the jcifs mailing list