1diff -ruNd --strip-trailing-cr jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java
2--- jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java  1970-01-01 01:00:00.000000000 +0100
3+++ jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java   2008-04-21 23:54:24.000000000 +0200
4@@ -0,0 +1,16 @@
5+package jcifs.dcerpc.msrpc;
6+
7+
8+public class MsrpcLookupNames extends lsarpc.LsarLookupNames {
9+    public MsrpcLookupNames(LsaPolicyHandle policyHandle, String names[]) {
10+   super(
11+       policyHandle,
12+       names,
13+       (short)1,
14+       0
15+   );
16+
17+        ptype = 0;
18+        flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG;
19+    }
20+}
21diff -ruNd --strip-trailing-cr jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/lsarpc.java jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/lsarpc.java
22--- jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/lsarpc.java    2008-04-25 19:34:39.000000000 +0200
23+++ jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/lsarpc.java 2008-05-23 16:44:42.000000000 +0200
24@@ -1,5 +1,7 @@
25 package jcifs.dcerpc.msrpc;
26
27+import java.nio.charset.Charset;
28+
29 import jcifs.dcerpc.*;
30 import jcifs.dcerpc.ndr.*;
31
32@@ -848,6 +850,93 @@
33             retval = (int)_src.dec_ndr_long();
34         }
35     }
36+    public static class LsarLookupNames extends DcerpcMessage {
37+   protected static final Charset csULU   = Charset.forName("UnicodeLittleUnmarked");
38+
39+   public int getOpnum() { return 0x0e; }
40+
41+   public int retval;
42+   public rpc.policy_handle handle;
43+   public String names[];
44+   public LsarRefDomainList domains;
45+   public LsarTransSidArray sids;
46+   public short level;
47+   public int count;
48+
49+   public LsarLookupNames(
50+       rpc.policy_handle handle,
51+       String names[],
52+       short level,
53+       int count
54+   ) {
55+       this.handle = handle;
56+       this.names = names;
57+       this.level = level;
58+       this.count = count;
59+   }
60+
61+   public void encode_in(NdrBuffer _dst) throws NdrException {
62+       handle.encode(_dst);
63+
64+       _dst.align(4);
65+
66+       _dst.enc_ndr_long(names.length);
67+       _dst.enc_ndr_long(names.length);
68+
69+       for(int i = 0; i < names.length; ++i) {
70+       int wlen = 2 * names[i].length();
71+
72+       _dst.enc_ndr_short(wlen);
73+       _dst.enc_ndr_short(wlen);
74+       _dst.enc_ndr_long(1);
75+       }
76+
77+       // Encode names
78+       for(int i = 0; i < names.length; ++i) {
79+       String name = names[i];
80+       int len = name.length();
81+
82+       _dst.enc_ndr_long(len);
83+       _dst.enc_ndr_long(0);
84+       _dst.enc_ndr_long(len);
85+
86+       System.arraycopy(
87+           name.getBytes(csULU), 0,
88+           _dst.buf, _dst.index,
89+           2 * len
90+       );
91+       _dst.advance(2 * len);
92+
93+       _dst.align(4);
94+       }
95+
96+       _dst.enc_ndr_long(0);   // num_trans_entries
97+       _dst.enc_ndr_long(0);   // ptr_trans_sids
98+
99+       _dst.enc_ndr_short(level);  // lookup_level
100+       _dst.align(4);
101+
102+       _dst.enc_ndr_long(count);   // mapped_count
103+   }
104+
105+   public void decode_out(NdrBuffer _src) throws NdrException {
106+            _src.align(4);
107+
108+       int _domainsp = _src.dec_ndr_long();
109+       if(_domainsp != 0) {
110+       if(domains == null) /* YOYOYO */
111+           domains = new LsarRefDomainList();
112+       domains.decode(_src);
113+       }
114+
115+       if(sids == null)
116+       sids = new LsarTransSidArray();
117+       sids.decode(_src);
118+
119+       count = (int)_src.dec_ndr_long();
120+       retval = (int)_src.dec_ndr_long();
121+   }
122+    }
123     public static class LsarOpenPolicy2 extends DcerpcMessage {
124
125         public int getOpnum() { return 0x2c; }
126diff -ruNd --strip-trailing-cr jcifs_1.2.20c/src/jcifs/smb/SID.java jcifs_1.2.20c+LsaLookupNames/src/jcifs/smb/SID.java
127--- jcifs_1.2.20c/src/jcifs/smb/SID.java    2008-04-25 19:34:39.000000000 +0200
128+++ jcifs_1.2.20c+LsaLookupNames/src/jcifs/smb/SID.java 2008-05-23 16:42:24.000000000 +0200
129@@ -696,5 +696,198 @@
130             }
131         }
132     }
133-}
134
135+    /**
136+     * <p>This function maps the array of domain object names <b>names</b> to their
137+     * equivalent <b>SID</b>s.</p>
138+     *
139+     * <p>Note that the LsaPolicyHandle passed to this function must be created at least
140+     * with access 0x00000800 (POLICY_LOOKUP_NAMES), otherwise it will throw an
141+     * IOException.</p>
142+     *
143+     * <p>On success, the returned <b>SID</b>s are named according the content of the
144+     * <b>names</b> array. Thereby, the case of their <b>acctName</b> fields may
145+     * be incorrect since names are mapped ignoring their case. If you want to
146+     * obtain the <b>acctName</b> exactly as it is stored in the server, you need
147+     * to issue a <b>resolve()</b> call on the <b>SID</b>, or use one of the
148+     * various <b>resolveSids()</b> variants. However, the domain part of the names
149+     * is always correct, since the server communicates it in its response.</p>
150+     *
151+     * <p>Also note that any unresolved name will map to a null value in the related
152+     * entry in the returned SIDs array. No exception will be thrown.</p>
153+     *
154+     * @param handle The <b>DcerpcHandle</b> object to use to communicate with the
155+     * LSA service
156+     * @param policyHandle The <b>LsaPolicyHandle</b> to use in order to get
157+     *  authorized by the LSA service.
158+     * @param names An array of strings containing the domain's object names to map.
159+     * @return An array of <b>SID</b>s one-to-one related with the given <b>names</b>.
160+     * @throws IOException if anything goes wrong
161+     * @author Giampaolo Tomassoni &lt;giampaolo at tomassoni dot biz&gt;
162+     */
163+    public static SID[] getFromNames(
164+   DcerpcHandle handle,
165+   LsaPolicyHandle policyHandle,
166+   String names[]
167+    ) throws IOException {
168+   SID outputSids[] = new SID[names.length];
169+   if(names.length > 0) {
170+       MsrpcLookupNames rpc = new MsrpcLookupNames(policyHandle, names);
171+       handle.sendrecv(rpc);
172+       switch (rpc.retval) {
173+       case 0:
174+       case NtStatus.NT_STATUS_NONE_MAPPED:
175+       case 0x00000107: // NT_STATUS_SOME_NOT_MAPPED
176+       break;
177+
178+       default:
179+       throw new SmbException(rpc.retval, false);
180+       }
181+
182+       SID domainSids[] = new SID[rpc.domains.count];
183+       for(int i = 0; i < domainSids.length; ++i) {
184+       SID domainSid = new SID(
185+           rpc.domains.domains[i].sid,
186+           SID_TYPE_DOMAIN,
187+           (new UnicodeString(rpc.domains.domains[i].name, false)).toString(),
188+           null,
189+           false
190+       );
191+
192+       domainSids[i] = domainSid;
193+       }
194+
195+       for(int i = 0; i < rpc.sids.count; ++i) {
196+       SID sid;
197+       switch(rpc.sids.sids[i].sid_type) {
198+       case SID_TYPE_DOMAIN:
199+           sid = domainSids[rpc.sids.sids[i].sid_index];
200+           break;
201+
202+       case SID_TYPE_INVALID:
203+       case SID_TYPE_UNKNOWN:
204+           // Probably the result of an attempt to resolve an
205+           // not existent or bad name
206+           sid = null;
207+           break;
208+
209+       default:
210+           SID domainSid = domainSids[rpc.sids.sids[i].sid_index];
211+           sid = new SID(domainSid, rpc.sids.sids[i].rid);
212+           sid.type = rpc.sids.sids[i].sid_type;
213+           sid.domainName = domainSid.domainName;
214+
215+           // If the specified name includes domain data, this must be
216+           // removed from acctName.
217+           sid.acctName = names[i].substring(names[i].indexOf('\\') + 1);
218+       }
219+
220+       outputSids[i] = sid;
221+       }
222+   }
223+
224+   return(outputSids);
225+    }
226+
227+    /**
228+     * <p>This function maps the array of domain object names <b>names</b> to their
229+     * equivalent <b>SID</b>s.</p>
230+     *
231+     * <p>On success, the returned <b>SID</b>s are named according the content of the
232+     * <b>names</b> array. Thereby, the case of their <b>acctName</b> fields may
233+     * be incorrect since names are mapped ignoring their case. If you want to
234+     * obtain the <b>acctName</b> exactly as it is stored in the server, you need
235+     * to issue a <b>resolve()</b> call on the <b>SID</b>, or use one of the
236+     * various <b>resolveSids()</b> variants. However, the domain part of the names
237+     * is always correct, since the server communicates it in its response.</p>
238+     *
239+     * <p>Also note that any unresolved name will map to a null value in the related
240+     * entry in the returned SIDs array. No exception will be thrown.</p>
241+     *
242+     * @param authorityServerName The name or address of the authority server to
243+     * contact to resolve the names.
244+     * @param auth The <b>NtlmPasswordAuthentication</b> to use in order to get
245+     *  authorized by the server.
246+     * @param names An array of strings containing the domain's object names to map.
247+     * @return An array of <b>SID</b>s one-to-one related with the given <b>names</b>.
248+     * @throws IOException if anything goes wrong
249+     * @author Giampaolo Tomassoni &lt;giampaolo at tomassoni dot biz&gt;
250+     */
251+    public static SID[] getFromNames(
252+   String authorityServerName,
253+   NtlmPasswordAuthentication auth,
254+   String names[]
255+    ) throws IOException {
256+   DcerpcHandle handle = DcerpcHandle.getHandle(
257+       "ncacn_np:" + authorityServerName + "[\\PIPE\\lsarpc]",
258+       auth
259+   );
260+   try {
261+       int dot = authorityServerName.indexOf('.');
262+
263+       String serverName;
264+       if(dot > 0 && !Character.isDigit(authorityServerName.charAt(0)))
265+       serverName = authorityServerName.substring(0, dot);
266+       else
267+       serverName = authorityServerName;
268+
269+       LsaPolicyHandle policyHandle = new LsaPolicyHandle(
270+       handle,
271+       "\\\\" + serverName,
272+       0x00000800  // POLICY_LOOKUP_NAMES
273+       );
274+            try { return(getFromNames(handle, policyHandle, names)); }
275+            finally { policyHandle.close(); }
276+        } finally { handle.close(); }
277+    }
278+
279+    /**
280+     * <p>This function is like the <b>getFromNames()</b> one, except that it maps a
281+     * single name to its <b>SID</b> equivalent.</p>
282+     *
283+     * <p>If you have more than one name to map, <b>getFromNames()</b> is much more
284+     * efficient.</p>
285+     *
286+     * @param handle The <b>DcerpcHandle</b> object to use to communicate with the
287+     * LSA service
288+     * @param policyHandle The <b>LsaPolicyHandle</b> to use in order to get
289+     *  authorized by the LSA service.
290+     * @param name A string containing the domain's object name to map.
291+     * @return The <b>SID</b>s mapped to the given <b>name</b>.
292+     * @throws IOException if anything goes wrong
293+     * @author Giampaolo Tomassoni &lt;giampaolo at tomassoni dot biz&gt;
294+     */
295+    public static SID getFromName(
296+   DcerpcHandle handle,
297+   LsaPolicyHandle policyHandle,
298+   String name
299+    ) throws IOException {
300+   SID sids[] = getFromNames(handle, policyHandle, new String[] { name });
301+   return(sids == null || sids.length == 0 ? null : sids[0]);
302+    }
303+
304+    /**
305+     * <p>This function is like the <b>getFromNames()</b> one, except that it maps a
306+     * single name to its <b>SID</b> equivalent.</p>
307+     *
308+     * <p>If you have more than one name to map, <b>getFromNames()</b> is much more
309+     * efficient.</p>
310+     *
311+     * @param authorityServerName The name or address of the authority server to
312+     * contact to resolve the names.
313+     * @param auth The <b>NtlmPasswordAuthentication</b> to use in order to get
314+     *  authorized by the server.
315+     * @param name A string containing the domain's object name to map.
316+     * @return The <b>SID</b>s mapped to the given <b>name</b>.
317+     * @throws IOException if anything goes wrong
318+     * @author Giampaolo Tomassoni &lt;giampaolo at tomassoni dot biz&gt;
319+     */
320+    public static SID getFromName(
321+   String authorityServerName,
322+   NtlmPasswordAuthentication auth,
323+   String name
324+    ) throws IOException {
325+   SID sids[] = getFromNames(authorityServerName, auth, new String[] { name });
326+   return(sids == null || sids.length == 0 ? null : sids[0]);
327+    }
328+}
329