SID.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. // This code is derived from jcifs smb client library <jcifs at samba dot org>
  2. // Ported by J. Arturo <webmaster at komodosoft dot net>
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License, or (at your option) any later version.
  8. //
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. using System;
  18. using System.Collections;
  19. using System.Collections.Generic;
  20. using System.IO;
  21. using SharpCifs.Dcerpc;
  22. using SharpCifs.Dcerpc.Msrpc;
  23. using SharpCifs.Util;
  24. using SharpCifs.Util.Sharpen;
  25. using Hashtable = SharpCifs.Util.Sharpen.Hashtable; //not System.Collections.Hashtable
  26. namespace SharpCifs.Smb
  27. {
  28. /// <summary>
  29. /// A Windows SID is a numeric identifier used to represent Windows
  30. /// accounts.
  31. /// </summary>
  32. /// <remarks>
  33. /// A Windows SID is a numeric identifier used to represent Windows
  34. /// accounts. SIDs are commonly represented using a textual format such as
  35. /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt> but they may
  36. /// also be resolved to yield the name of the associated Windows account
  37. /// such as <tt>Administrators</tt> or <tt>MYDOM\alice</tt>.
  38. /// <p>
  39. /// Consider the following output of <tt>examples/SidLookup.java</tt>:
  40. /// <pre>
  41. /// toString: S-1-5-21-4133388617-793952518-2001621813-512
  42. /// toDisplayString: WNET\Domain Admins
  43. /// getType: 2
  44. /// getTypeText: Domain group
  45. /// getDomainName: WNET
  46. /// getAccountName: Domain Admins
  47. /// </pre>
  48. /// </remarks>
  49. public class Sid : Rpc.SidT
  50. {
  51. public const int SidTypeUseNone = Lsarpc.SidNameUseNone;
  52. public const int SidTypeUser = Lsarpc.SidNameUser;
  53. public const int SidTypeDomGrp = Lsarpc.SidNameDomGrp;
  54. public const int SidTypeDomain = Lsarpc.SidNameDomain;
  55. public const int SidTypeAlias = Lsarpc.SidNameAlias;
  56. public const int SidTypeWknGrp = Lsarpc.SidNameWknGrp;
  57. public const int SidTypeDeleted = Lsarpc.SidNameDeleted;
  58. public const int SidTypeInvalid = Lsarpc.SidNameInvalid;
  59. public const int SidTypeUnknown = Lsarpc.SidNameUnknown;
  60. internal static readonly string[] SidTypeNames =
  61. {
  62. "0", "User", "Domain group", "Domain", "Local group",
  63. "Builtin group", "Deleted", "Invalid", "Unknown"
  64. };
  65. public const int SidFlagResolveSids = unchecked(0x0001);
  66. public static Sid Everyone;
  67. public static Sid CreatorOwner;
  68. public static Sid SYSTEM;
  69. static Sid()
  70. {
  71. try
  72. {
  73. Everyone = new Sid("S-1-1-0");
  74. CreatorOwner = new Sid("S-1-3-0");
  75. SYSTEM = new Sid("S-1-5-18");
  76. }
  77. catch (SmbException)
  78. {
  79. }
  80. }
  81. internal static Hashtable SidCache = new Hashtable();
  82. /// <exception cref="System.IO.IOException"></exception>
  83. internal static void ResolveSids(DcerpcHandle handle,
  84. LsaPolicyHandle policyHandle,
  85. Sid[] sids)
  86. {
  87. MsrpcLookupSids rpc = new MsrpcLookupSids(policyHandle, sids);
  88. handle.Sendrecv(rpc);
  89. switch (rpc.Retval)
  90. {
  91. case 0:
  92. case NtStatus.NtStatusNoneMapped:
  93. case unchecked(0x00000107):
  94. {
  95. // NT_STATUS_SOME_NOT_MAPPED
  96. break;
  97. }
  98. default:
  99. {
  100. throw new SmbException(rpc.Retval, false);
  101. }
  102. }
  103. for (int si = 0; si < sids.Length; si++)
  104. {
  105. sids[si].Type = rpc.Names.Names[si].SidType;
  106. sids[si].DomainName = null;
  107. switch (sids[si].Type)
  108. {
  109. case SidTypeUser:
  110. case SidTypeDomGrp:
  111. case SidTypeDomain:
  112. case SidTypeAlias:
  113. case SidTypeWknGrp:
  114. {
  115. int sidIndex = rpc.Names.Names[si].SidIndex;
  116. Rpc.Unicode_string ustr = rpc.Domains.Domains[sidIndex].Name;
  117. sids[si].DomainName = (new UnicodeString(ustr, false)).ToString();
  118. break;
  119. }
  120. }
  121. sids[si].AcctName = (new UnicodeString(rpc.Names.Names[si].Name, false)).ToString();
  122. sids[si].OriginServer = null;
  123. sids[si].OriginAuth = null;
  124. }
  125. }
  126. /// <exception cref="System.IO.IOException"></exception>
  127. internal static void ResolveSids0(string authorityServerName,
  128. NtlmPasswordAuthentication auth,
  129. Sid[] sids)
  130. {
  131. DcerpcHandle handle = null;
  132. LsaPolicyHandle policyHandle = null;
  133. lock (SidCache)
  134. {
  135. try
  136. {
  137. handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName
  138. + "[\\PIPE\\lsarpc]", auth);
  139. string server = authorityServerName;
  140. int dot = server.IndexOf('.');
  141. if (dot > 0 && char.IsDigit(server[0]) == false)
  142. {
  143. server = Runtime.Substring(server, 0, dot);
  144. }
  145. policyHandle = new LsaPolicyHandle(handle, "\\\\" + server, unchecked(0x00000800));
  146. ResolveSids(handle, policyHandle, sids);
  147. }
  148. finally
  149. {
  150. if (handle != null)
  151. {
  152. if (policyHandle != null)
  153. {
  154. policyHandle.Close();
  155. }
  156. handle.Close();
  157. }
  158. }
  159. }
  160. }
  161. /// <exception cref="System.IO.IOException"></exception>
  162. public static void ResolveSids(string authorityServerName,
  163. NtlmPasswordAuthentication auth,
  164. Sid[] sids,
  165. int offset,
  166. int length)
  167. {
  168. List<object> list = new List<object>(); //new List<object>(sids.Length);
  169. int si;
  170. lock (SidCache)
  171. {
  172. for (si = 0; si < length; si++)
  173. {
  174. Sid sid = (Sid)SidCache.Get(sids[offset + si]);
  175. if (sid != null)
  176. {
  177. sids[offset + si].Type = sid.Type;
  178. sids[offset + si].DomainName = sid.DomainName;
  179. sids[offset + si].AcctName = sid.AcctName;
  180. }
  181. else
  182. {
  183. list.Add(sids[offset + si]);
  184. }
  185. }
  186. if (list.Count > 0)
  187. {
  188. //sids = (Jcifs.Smb.SID[])Sharpen.Collections.ToArray(list, new Jcifs.Smb.SID[0]);
  189. sids = (Sid[])list.ToArray();
  190. ResolveSids0(authorityServerName, auth, sids);
  191. for (si = 0; si < sids.Length; si++)
  192. {
  193. SidCache.Put(sids[si], sids[si]);
  194. }
  195. }
  196. }
  197. }
  198. /// <summary>Resolve an array of SIDs using a cache and at most one MSRPC request.</summary>
  199. /// <remarks>
  200. /// Resolve an array of SIDs using a cache and at most one MSRPC request.
  201. ///
  202. /// This method will attempt
  203. /// to resolve SIDs using a cache and cache the results of any SIDs that
  204. /// required resolving with the authority. SID cache entries are currently not
  205. /// expired because under normal circumstances SID information never changes.
  206. /// </remarks>
  207. /// <param name="authorityServerName">
  208. /// The hostname of the server that should be queried. For maximum efficiency this should be the hostname of a domain controller however a member server will work as well and a domain controller may not return names for SIDs corresponding to local accounts for which the domain controller is not an authority.
  209. /// </param>
  210. /// <param name="auth">
  211. /// The credentials that should be used to communicate with the named server. As usual, <tt>null</tt> indicates that default credentials should be used.
  212. /// </param>
  213. /// <param name="sids">
  214. /// The SIDs that should be resolved. After this function is called, the names associated with the SIDs may be queried with the <tt>toDisplayString</tt>, <tt>getDomainName</tt>, and <tt>getAccountName</tt> methods.
  215. /// </param>
  216. /// <exception cref="System.IO.IOException"></exception>
  217. public static void ResolveSids(string authorityServerName,
  218. NtlmPasswordAuthentication auth,
  219. Sid[] sids)
  220. {
  221. List<object> list = new List<object>(); //new List<object>(sids.Length);
  222. int si;
  223. lock (SidCache)
  224. {
  225. for (si = 0; si < sids.Length; si++)
  226. {
  227. Sid sid = (Sid)SidCache.Get(sids[si]);
  228. if (sid != null)
  229. {
  230. sids[si].Type = sid.Type;
  231. sids[si].DomainName = sid.DomainName;
  232. sids[si].AcctName = sid.AcctName;
  233. }
  234. else
  235. {
  236. list.Add(sids[si]);
  237. }
  238. }
  239. if (list.Count > 0)
  240. {
  241. //sids = (Jcifs.Smb.SID[])Sharpen.Collections.ToArray(list, new Jcifs.Smb.SID[0]);
  242. sids = (Sid[])list.ToArray();
  243. ResolveSids0(authorityServerName, auth, sids);
  244. for (si = 0; si < sids.Length; si++)
  245. {
  246. SidCache.Put(sids[si], sids[si]);
  247. }
  248. }
  249. }
  250. }
  251. /// <exception cref="System.IO.IOException"></exception>
  252. public static Sid GetServerSid(string server,
  253. NtlmPasswordAuthentication auth)
  254. {
  255. DcerpcHandle handle = null;
  256. LsaPolicyHandle policyHandle = null;
  257. Lsarpc.LsarDomainInfo info = new Lsarpc.LsarDomainInfo();
  258. MsrpcQueryInformationPolicy rpc;
  259. lock (SidCache)
  260. {
  261. try
  262. {
  263. handle = DcerpcHandle.GetHandle("ncacn_np:" + server + "[\\PIPE\\lsarpc]", auth);
  264. // NetApp doesn't like the 'generic' access mask values
  265. policyHandle = new LsaPolicyHandle(handle, null, unchecked(0x00000001));
  266. rpc = new MsrpcQueryInformationPolicy(policyHandle,
  267. Lsarpc.PolicyInfoAccountDomain,
  268. info);
  269. handle.Sendrecv(rpc);
  270. if (rpc.Retval != 0)
  271. {
  272. throw new SmbException(rpc.Retval, false);
  273. }
  274. return new Sid(info.Sid,
  275. SidTypeDomain,
  276. (new UnicodeString(info.Name, false)).ToString(),
  277. null,
  278. false);
  279. }
  280. finally
  281. {
  282. if (handle != null)
  283. {
  284. if (policyHandle != null)
  285. {
  286. policyHandle.Close();
  287. }
  288. handle.Close();
  289. }
  290. }
  291. }
  292. }
  293. public static byte[] ToByteArray(Rpc.SidT sid)
  294. {
  295. byte[] dst = new byte[1 + 1 + 6 + sid.SubAuthorityCount * 4];
  296. int di = 0;
  297. dst[di++] = sid.Revision;
  298. dst[di++] = sid.SubAuthorityCount;
  299. Array.Copy(sid.IdentifierAuthority, 0, dst, di, 6);
  300. di += 6;
  301. for (int ii = 0; ii < sid.SubAuthorityCount; ii++)
  302. {
  303. Encdec.Enc_uint32le(sid.SubAuthority[ii], dst, di);
  304. di += 4;
  305. }
  306. return dst;
  307. }
  308. internal int Type;
  309. internal string DomainName;
  310. internal string AcctName;
  311. internal string OriginServer;
  312. internal NtlmPasswordAuthentication OriginAuth;
  313. public Sid(byte[] src, int si)
  314. {
  315. Revision = src[si++];
  316. SubAuthorityCount = src[si++];
  317. IdentifierAuthority = new byte[6];
  318. Array.Copy(src, si, IdentifierAuthority, 0, 6);
  319. si += 6;
  320. if (SubAuthorityCount > 100)
  321. {
  322. throw new RuntimeException("Invalid SID sub_authority_count");
  323. }
  324. SubAuthority = new int[SubAuthorityCount];
  325. for (int i = 0; i < SubAuthorityCount; i++)
  326. {
  327. SubAuthority[i] = ServerMessageBlock.ReadInt4(src, si);
  328. si += 4;
  329. }
  330. }
  331. /// <summary>
  332. /// Construct a SID from it's textual representation such as
  333. /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>.
  334. /// </summary>
  335. /// <remarks>
  336. /// Construct a SID from it's textual representation such as
  337. /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>.
  338. /// </remarks>
  339. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  340. public Sid(string textual)
  341. {
  342. StringTokenizer st = new StringTokenizer(textual, "-");
  343. if (st.CountTokens() < 3 || !st.NextToken().Equals("S"))
  344. {
  345. // need S-N-M
  346. throw new SmbException("Bad textual SID format: " + textual);
  347. }
  348. Revision = byte.Parse(st.NextToken());
  349. string tmp = st.NextToken();
  350. long id = 0;
  351. if (tmp.StartsWith("0x"))
  352. {
  353. //id = long.Parse(Sharpen.Runtime.Substring(tmp, 2), 16);
  354. id = long.Parse(Runtime.Substring(tmp, 2));
  355. }
  356. else
  357. {
  358. id = long.Parse(tmp);
  359. }
  360. IdentifierAuthority = new byte[6];
  361. for (int i = 5; id > 0; i--)
  362. {
  363. IdentifierAuthority[i] = unchecked((byte)(id % 256));
  364. id >>= 8;
  365. }
  366. SubAuthorityCount = unchecked((byte)st.CountTokens());
  367. if (SubAuthorityCount > 0)
  368. {
  369. SubAuthority = new int[SubAuthorityCount];
  370. for (int i1 = 0; i1 < SubAuthorityCount; i1++)
  371. {
  372. SubAuthority[i1] = (int)(long.Parse(st.NextToken()) & unchecked(0xFFFFFFFFL));
  373. }
  374. }
  375. }
  376. /// <summary>
  377. /// Construct a SID from a domain SID and an RID
  378. /// (relative identifier).
  379. /// </summary>
  380. /// <remarks>
  381. /// Construct a SID from a domain SID and an RID
  382. /// (relative identifier). For example, a domain SID
  383. /// <tt>S-1-5-21-1496946806-2192648263-3843101252</tt> and RID <tt>1029</tt> would
  384. /// yield the SID <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>.
  385. /// </remarks>
  386. public Sid(Sid domsid, int rid)
  387. {
  388. Revision = domsid.Revision;
  389. IdentifierAuthority = domsid.IdentifierAuthority;
  390. SubAuthorityCount = unchecked((byte)(domsid.SubAuthorityCount + 1));
  391. SubAuthority = new int[SubAuthorityCount];
  392. int i;
  393. for (i = 0; i < domsid.SubAuthorityCount; i++)
  394. {
  395. SubAuthority[i] = domsid.SubAuthority[i];
  396. }
  397. SubAuthority[i] = rid;
  398. }
  399. public Sid(Rpc.SidT sid,
  400. int type,
  401. string domainName,
  402. string acctName,
  403. bool decrementAuthority)
  404. {
  405. Revision = sid.Revision;
  406. SubAuthorityCount = sid.SubAuthorityCount;
  407. IdentifierAuthority = sid.IdentifierAuthority;
  408. SubAuthority = sid.SubAuthority;
  409. this.Type = type;
  410. this.DomainName = domainName;
  411. this.AcctName = acctName;
  412. if (decrementAuthority)
  413. {
  414. SubAuthorityCount--;
  415. SubAuthority = new int[SubAuthorityCount];
  416. for (int i = 0; i < SubAuthorityCount; i++)
  417. {
  418. SubAuthority[i] = sid.SubAuthority[i];
  419. }
  420. }
  421. }
  422. public virtual Sid GetDomainSid()
  423. {
  424. return new Sid(this,
  425. SidTypeDomain,
  426. DomainName,
  427. null,
  428. GetType() != SidTypeDomain);
  429. }
  430. public virtual int GetRid()
  431. {
  432. if (GetType() == SidTypeDomain)
  433. {
  434. throw new ArgumentException("This SID is a domain sid");
  435. }
  436. return SubAuthority[SubAuthorityCount - 1];
  437. }
  438. /// <summary>Returns the type of this SID indicating the state or type of account.</summary>
  439. /// <remarks>
  440. /// Returns the type of this SID indicating the state or type of account.
  441. /// <p>
  442. /// SID types are described in the following table.
  443. /// <tt>
  444. /// <table>
  445. /// <tr><th>Type</th><th>Name</th></tr>
  446. /// <tr><td>SID_TYPE_USE_NONE</td><td>0</td></tr>
  447. /// <tr><td>SID_TYPE_USER</td><td>User</td></tr>
  448. /// <tr><td>SID_TYPE_DOM_GRP</td><td>Domain group</td></tr>
  449. /// <tr><td>SID_TYPE_DOMAIN</td><td>Domain</td></tr>
  450. /// <tr><td>SID_TYPE_ALIAS</td><td>Local group</td></tr>
  451. /// <tr><td>SID_TYPE_WKN_GRP</td><td>Builtin group</td></tr>
  452. /// <tr><td>SID_TYPE_DELETED</td><td>Deleted</td></tr>
  453. /// <tr><td>SID_TYPE_INVALID</td><td>Invalid</td></tr>
  454. /// <tr><td>SID_TYPE_UNKNOWN</td><td>Unknown</td></tr>
  455. /// </table>
  456. /// </tt>
  457. /// </remarks>
  458. public virtual int GetType()
  459. {
  460. if (OriginServer != null)
  461. {
  462. ResolveWeak();
  463. }
  464. return Type;
  465. }
  466. /// <summary>
  467. /// Return text represeting the SID type suitable for display to
  468. /// users.
  469. /// </summary>
  470. /// <remarks>
  471. /// Return text represeting the SID type suitable for display to
  472. /// users. Text includes 'User', 'Domain group', 'Local group', etc.
  473. /// </remarks>
  474. public virtual string GetTypeText()
  475. {
  476. if (OriginServer != null)
  477. {
  478. ResolveWeak();
  479. }
  480. return SidTypeNames[Type];
  481. }
  482. /// <summary>
  483. /// Return the domain name of this SID unless it could not be
  484. /// resolved in which case the numeric representation is returned.
  485. /// </summary>
  486. /// <remarks>
  487. /// Return the domain name of this SID unless it could not be
  488. /// resolved in which case the numeric representation is returned.
  489. /// </remarks>
  490. public virtual string GetDomainName()
  491. {
  492. if (OriginServer != null)
  493. {
  494. ResolveWeak();
  495. }
  496. if (Type == SidTypeUnknown)
  497. {
  498. string full = ToString();
  499. return Runtime.Substring(full, 0, full.Length - GetAccountName().Length - 1);
  500. }
  501. return DomainName;
  502. }
  503. /// <summary>
  504. /// Return the sAMAccountName of this SID unless it could not
  505. /// be resolved in which case the numeric RID is returned.
  506. /// </summary>
  507. /// <remarks>
  508. /// Return the sAMAccountName of this SID unless it could not
  509. /// be resolved in which case the numeric RID is returned. If this
  510. /// SID is a domain SID, this method will return an empty String.
  511. /// </remarks>
  512. public virtual string GetAccountName()
  513. {
  514. if (OriginServer != null)
  515. {
  516. ResolveWeak();
  517. }
  518. if (Type == SidTypeUnknown)
  519. {
  520. return string.Empty + SubAuthority[SubAuthorityCount - 1];
  521. }
  522. if (Type == SidTypeDomain)
  523. {
  524. return string.Empty;
  525. }
  526. return AcctName;
  527. }
  528. public override int GetHashCode()
  529. {
  530. int hcode = IdentifierAuthority[5];
  531. for (int i = 0; i < SubAuthorityCount; i++)
  532. {
  533. hcode += 65599 * SubAuthority[i];
  534. }
  535. return hcode;
  536. }
  537. public override bool Equals(object obj)
  538. {
  539. if (obj is Sid)
  540. {
  541. Sid sid = (Sid)obj;
  542. if (sid == this)
  543. {
  544. return true;
  545. }
  546. if (sid.SubAuthorityCount == SubAuthorityCount)
  547. {
  548. int i = SubAuthorityCount;
  549. while (i-- > 0)
  550. {
  551. if (sid.SubAuthority[i] != SubAuthority[i])
  552. {
  553. return false;
  554. }
  555. }
  556. for (i = 0; i < 6; i++)
  557. {
  558. if (sid.IdentifierAuthority[i] != IdentifierAuthority[i])
  559. {
  560. return false;
  561. }
  562. }
  563. return sid.Revision == Revision;
  564. }
  565. }
  566. return false;
  567. }
  568. /// <summary>
  569. /// Return the numeric representation of this sid such as
  570. /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>.
  571. /// </summary>
  572. /// <remarks>
  573. /// Return the numeric representation of this sid such as
  574. /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>.
  575. /// </remarks>
  576. public override string ToString()
  577. {
  578. string ret = "S-" + (Revision & unchecked(0xFF)) + "-";
  579. if (IdentifierAuthority[0] != unchecked(0)
  580. || IdentifierAuthority[1] != unchecked(0))
  581. {
  582. ret += "0x";
  583. ret += Hexdump.ToHexString(IdentifierAuthority, 0, 6);
  584. }
  585. else
  586. {
  587. int shift = 0;
  588. long id = 0;
  589. for (int i = 5; i > 1; i--)
  590. {
  591. id += (IdentifierAuthority[i] & unchecked(0xFFL)) << shift;
  592. shift += 8;
  593. }
  594. ret += id;
  595. }
  596. for (int i1 = 0; i1 < SubAuthorityCount; i1++)
  597. {
  598. ret += "-" + (SubAuthority[i1] & unchecked(0xFFFFFFFFL));
  599. }
  600. return ret;
  601. }
  602. /// <summary>
  603. /// Return a String representing this SID ideal for display to
  604. /// users.
  605. /// </summary>
  606. /// <remarks>
  607. /// Return a String representing this SID ideal for display to
  608. /// users. This method should return the same text that the ACL
  609. /// editor in Windows would display.
  610. /// <p>
  611. /// Specifically, if the SID has
  612. /// been resolved and it is not a domain SID or builtin account,
  613. /// the full DOMAIN\name form of the account will be
  614. /// returned (e.g. MYDOM\alice or MYDOM\Domain Users).
  615. /// If the SID has been resolved but it is is a domain SID,
  616. /// only the domain name will be returned (e.g. MYDOM).
  617. /// If the SID has been resolved but it is a builtin account,
  618. /// only the name component will be returned (e.g. SYSTEM).
  619. /// If the sid cannot be resolved the numeric representation from
  620. /// toString() is returned.
  621. /// </remarks>
  622. public virtual string ToDisplayString()
  623. {
  624. if (OriginServer != null)
  625. {
  626. ResolveWeak();
  627. }
  628. if (DomainName != null)
  629. {
  630. string str;
  631. if (Type == SidTypeDomain)
  632. {
  633. str = DomainName;
  634. }
  635. else
  636. {
  637. if (Type == SidTypeWknGrp || DomainName.Equals("BUILTIN"))
  638. {
  639. if (Type == SidTypeUnknown)
  640. {
  641. str = ToString();
  642. }
  643. else
  644. {
  645. str = AcctName;
  646. }
  647. }
  648. else
  649. {
  650. str = DomainName + "\\" + AcctName;
  651. }
  652. }
  653. return str;
  654. }
  655. return ToString();
  656. }
  657. /// <summary>Manually resolve this SID.</summary>
  658. /// <remarks>
  659. /// Manually resolve this SID. Normally SIDs are automatically
  660. /// resolved. However, if a SID is constructed explicitly using a SID
  661. /// constructor, JCIFS will have no knowledge of the server that created the
  662. /// SID and therefore cannot possibly resolve it automatically. In this case,
  663. /// this method will be necessary.
  664. /// </remarks>
  665. /// <param name="authorityServerName">The FQDN of the server that is an authority for the SID.
  666. /// </param>
  667. /// <param name="auth">Credentials suitable for accessing the SID's information.</param>
  668. /// <exception cref="System.IO.IOException"></exception>
  669. public virtual void Resolve(string authorityServerName,
  670. NtlmPasswordAuthentication auth)
  671. {
  672. Sid[] sids = new Sid[1];
  673. sids[0] = this;
  674. ResolveSids(authorityServerName, auth, sids);
  675. }
  676. internal virtual void ResolveWeak()
  677. {
  678. if (OriginServer != null)
  679. {
  680. try
  681. {
  682. Resolve(OriginServer, OriginAuth);
  683. }
  684. catch (IOException)
  685. {
  686. }
  687. finally
  688. {
  689. OriginServer = null;
  690. OriginAuth = null;
  691. }
  692. }
  693. }
  694. /// <exception cref="System.IO.IOException"></exception>
  695. internal static Sid[] GetGroupMemberSids0(DcerpcHandle handle,
  696. SamrDomainHandle domainHandle,
  697. Sid domsid,
  698. int rid,
  699. int flags)
  700. {
  701. SamrAliasHandle aliasHandle = null;
  702. Lsarpc.LsarSidArray sidarray = new Lsarpc.LsarSidArray();
  703. MsrpcGetMembersInAlias rpc = null;
  704. try
  705. {
  706. aliasHandle = new SamrAliasHandle(handle, domainHandle, unchecked(0x0002000c), rid);
  707. rpc = new MsrpcGetMembersInAlias(aliasHandle, sidarray);
  708. handle.Sendrecv(rpc);
  709. if (rpc.Retval != 0)
  710. {
  711. throw new SmbException(rpc.Retval, false);
  712. }
  713. Sid[] sids = new Sid[rpc.Sids.NumSids];
  714. string originServer = handle.GetServer();
  715. NtlmPasswordAuthentication originAuth
  716. = (NtlmPasswordAuthentication)handle.GetPrincipal();
  717. for (int i = 0; i < sids.Length; i++)
  718. {
  719. sids[i] = new Sid(rpc.Sids.Sids[i].Sid, 0, null, null, false);
  720. sids[i].OriginServer = originServer;
  721. sids[i].OriginAuth = originAuth;
  722. }
  723. if (sids.Length > 0 && (flags & SidFlagResolveSids) != 0)
  724. {
  725. ResolveSids(originServer, originAuth, sids);
  726. }
  727. return sids;
  728. }
  729. finally
  730. {
  731. if (aliasHandle != null)
  732. {
  733. aliasHandle.Close();
  734. }
  735. }
  736. }
  737. /// <exception cref="System.IO.IOException"></exception>
  738. public virtual Sid[] GetGroupMemberSids(string authorityServerName,
  739. NtlmPasswordAuthentication auth,
  740. int flags)
  741. {
  742. if (Type != SidTypeDomGrp && Type != SidTypeAlias)
  743. {
  744. return new Sid[0];
  745. }
  746. DcerpcHandle handle = null;
  747. SamrPolicyHandle policyHandle = null;
  748. SamrDomainHandle domainHandle = null;
  749. Sid domsid = GetDomainSid();
  750. lock (SidCache)
  751. {
  752. try
  753. {
  754. handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName
  755. + "[\\PIPE\\samr]", auth);
  756. policyHandle = new SamrPolicyHandle(handle,
  757. authorityServerName,
  758. unchecked(0x00000030));
  759. domainHandle = new SamrDomainHandle(handle,
  760. policyHandle,
  761. unchecked(0x00000200),
  762. domsid);
  763. return GetGroupMemberSids0(handle,
  764. domainHandle,
  765. domsid,
  766. GetRid(),
  767. flags);
  768. }
  769. finally
  770. {
  771. if (handle != null)
  772. {
  773. if (policyHandle != null)
  774. {
  775. if (domainHandle != null)
  776. {
  777. domainHandle.Close();
  778. }
  779. policyHandle.Close();
  780. }
  781. handle.Close();
  782. }
  783. }
  784. }
  785. }
  786. /// <summary>
  787. /// This specialized method returns a Map of users and local groups for the
  788. /// target server where keys are SIDs representing an account and each value
  789. /// is an List<object> of SIDs represents the local groups that the account is
  790. /// a member of.
  791. /// </summary>
  792. /// <remarks>
  793. /// This specialized method returns a Map of users and local groups for the
  794. /// target server where keys are SIDs representing an account and each value
  795. /// is an List<object> of SIDs represents the local groups that the account is
  796. /// a member of.
  797. /// <p/>
  798. /// This method is designed to assist with computing access control for a
  799. /// given user when the target object's ACL has local groups. Local groups
  800. /// are not listed in a user's group membership (e.g. as represented by the
  801. /// tokenGroups constructed attribute retrived via LDAP).
  802. /// <p/>
  803. /// Domain groups nested inside a local group are currently not expanded. In
  804. /// this case the key (SID) type will be SID_TYPE_DOM_GRP rather than
  805. /// SID_TYPE_USER.
  806. /// </remarks>
  807. /// <param name="authorityServerName">The server from which the local groups will be queried.
  808. /// </param>
  809. /// <param name="auth">The credentials required to query groups and group members.</param>
  810. /// <param name="flags">
  811. /// Flags that control the behavior of the operation. When all
  812. /// name associated with SIDs will be required, the SID_FLAG_RESOLVE_SIDS
  813. /// flag should be used which causes all group member SIDs to be resolved
  814. /// together in a single more efficient operation.
  815. /// </param>
  816. /// <exception cref="System.IO.IOException"></exception>
  817. internal static Hashtable GetLocalGroupsMap(string authorityServerName, NtlmPasswordAuthentication
  818. auth, int flags)
  819. {
  820. Sid domsid = GetServerSid(authorityServerName, auth);
  821. DcerpcHandle handle = null;
  822. SamrPolicyHandle policyHandle = null;
  823. SamrDomainHandle domainHandle = null;
  824. Samr.SamrSamArray sam = new Samr.SamrSamArray();
  825. MsrpcEnumerateAliasesInDomain rpc;
  826. lock (SidCache)
  827. {
  828. try
  829. {
  830. handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName
  831. + "[\\PIPE\\samr]", auth);
  832. policyHandle = new SamrPolicyHandle(handle,
  833. authorityServerName,
  834. unchecked(0x02000000));
  835. domainHandle = new SamrDomainHandle(handle,
  836. policyHandle,
  837. unchecked(0x02000000),
  838. domsid);
  839. rpc = new MsrpcEnumerateAliasesInDomain(domainHandle,
  840. unchecked(0xFFFF),
  841. sam);
  842. handle.Sendrecv(rpc);
  843. if (rpc.Retval != 0)
  844. {
  845. throw new SmbException(rpc.Retval, false);
  846. }
  847. Hashtable map = new Hashtable();
  848. for (int ei = 0; ei < rpc.Sam.Count; ei++)
  849. {
  850. Samr.SamrSamEntry entry = rpc.Sam.Entries[ei];
  851. Sid[] mems = GetGroupMemberSids0(handle,
  852. domainHandle,
  853. domsid,
  854. entry.Idx,
  855. flags);
  856. Sid groupSid = new Sid(domsid, entry.Idx);
  857. groupSid.Type = SidTypeAlias;
  858. groupSid.DomainName = domsid.GetDomainName();
  859. groupSid.AcctName = (new UnicodeString(entry.Name, false)).ToString();
  860. for (int mi = 0; mi < mems.Length; mi++)
  861. {
  862. List<object> groups = (List<object>)map.Get(mems[mi]);
  863. if (groups == null)
  864. {
  865. groups = new List<object>();
  866. map.Put(mems[mi], groups);
  867. }
  868. if (!groups.Contains(groupSid))
  869. {
  870. groups.Add(groupSid);
  871. }
  872. }
  873. }
  874. return map;
  875. }
  876. finally
  877. {
  878. if (handle != null)
  879. {
  880. if (policyHandle != null)
  881. {
  882. if (domainHandle != null)
  883. {
  884. domainHandle.Close();
  885. }
  886. policyHandle.Close();
  887. }
  888. handle.Close();
  889. }
  890. }
  891. }
  892. }
  893. }
  894. }