1 19 20 package jcifs.smb; 21 22 import java.util.*; 23 import java.io.IOException ; 24 25 import jcifs.util.Hexdump; 26 import jcifs.dcerpc.*; 27 import jcifs.dcerpc.msrpc.*; 28 29 46 47 public class SID extends rpc.sid_t { 48 49 public static final int SID_TYPE_USE_NONE = lsarpc.SID_NAME_USE_NONE; 50 public static final int SID_TYPE_USER = lsarpc.SID_NAME_USER; 51 public static final int SID_TYPE_DOM_GRP = lsarpc.SID_NAME_DOM_GRP; 52 public static final int SID_TYPE_DOMAIN = lsarpc.SID_NAME_DOMAIN; 53 public static final int SID_TYPE_ALIAS = lsarpc.SID_NAME_ALIAS; 54 public static final int SID_TYPE_WKN_GRP = lsarpc.SID_NAME_WKN_GRP; 55 public static final int SID_TYPE_DELETED = lsarpc.SID_NAME_DELETED; 56 public static final int SID_TYPE_INVALID = lsarpc.SID_NAME_INVALID; 57 public static final int SID_TYPE_UNKNOWN = lsarpc.SID_NAME_UNKNOWN; 58 59 static final String [] SID_TYPE_NAMES = { 60 "0", 61 "User", 62 "Domain group", 63 "Domain", 64 "Local group", 65 "Builtin group", 66 "Deleted", 67 "Invalid", 68 "Unknown" 69 }; 70 71 public static final int SID_FLAG_RESOLVE_SIDS = 0x0001; 72 73 public static SID EVERYONE = null; 74 public static SID CREATOR_OWNER = null; 75 public static SID SYSTEM = null; 76 77 static { 78 try { 79 EVERYONE = new SID("S-1-1-0"); 80 CREATOR_OWNER = new SID("S-1-3-0"); 81 SYSTEM = new SID("S-1-5-18"); 82 } catch (SmbException se) { 83 } 84 } 85 86 static Map sid_cache = Collections.synchronizedMap(new HashMap()); 87 88 static void resolveSids(DcerpcHandle handle, 89 LsaPolicyHandle policyHandle, 90 SID[] sids) throws IOException { 91 MsrpcLookupSids rpc = new MsrpcLookupSids(policyHandle, sids); 92 handle.sendrecv(rpc); 93 switch (rpc.retval) { 94 case 0: 95 case NtStatus.NT_STATUS_NONE_MAPPED: 96 case 0x00000107: break; 98 default: 99 throw new SmbException(rpc.retval, false); 100 } 101 102 for (int si = 0; si < sids.length; si++) { 103 sids[si].type = rpc.names.names[si].sid_type; 104 sids[si].domainName = null; 105 106 switch (sids[si].type) { 107 case SID_TYPE_USER: 108 case SID_TYPE_DOM_GRP: 109 case SID_TYPE_DOMAIN: 110 case SID_TYPE_ALIAS: 111 case SID_TYPE_WKN_GRP: 112 int sid_index = rpc.names.names[si].sid_index; 113 rpc.unicode_string ustr = rpc.domains.domains[sid_index].name; 114 sids[si].domainName = (new UnicodeString(ustr, false)).toString(); 115 break; 116 } 117 118 sids[si].acctName = (new UnicodeString(rpc.names.names[si].name, false)).toString(); 119 sids[si].origin_server = null; 120 sids[si].origin_auth = null; 121 } 122 } 123 static void resolveSids0(String authorityServerName, 124 NtlmPasswordAuthentication auth, 125 SID[] sids) throws IOException { 126 DcerpcHandle handle = null; 127 LsaPolicyHandle policyHandle = null; 128 129 try { 130 handle = DcerpcHandle.getHandle("ncacn_np:" + authorityServerName + 131 "[\\PIPE\\lsarpc]", auth); 132 String server = authorityServerName; 133 int dot = server.indexOf('.'); 134 if (dot > 0 && Character.isDigit(server.charAt(0)) == false) 135 server = server.substring(0, dot); 136 policyHandle = new LsaPolicyHandle(handle, "\\\\" + server, 0x00000800); 137 SID.resolveSids(handle, policyHandle, sids); 138 } finally { 139 if (handle != null) { 140 if (policyHandle != null) { 141 policyHandle.close(); 142 } 143 handle.close(); 144 } 145 } 146 } 147 148 160 static public void resolveSids(String authorityServerName, 161 NtlmPasswordAuthentication auth, 162 SID[] sids) throws IOException { 163 ArrayList list = new ArrayList(sids.length); 164 int si; 165 166 for (si = 0; si < sids.length; si++) { 167 SID sid = (SID)sid_cache.get(sids[si]); 168 if (sid != null) { 169 sids[si].type = sid.type; 170 sids[si].domainName = sid.domainName; 171 sids[si].acctName = sid.acctName; 172 } else { 173 list.add(sids[si]); 174 } 175 } 176 177 if (list.size() > 0) { 178 sids = (SID[])list.toArray(new SID[0]); 179 SID.resolveSids0(authorityServerName, auth, sids); 180 for (si = 0; si < sids.length; si++) { 181 sid_cache.put(sids[si], sids[si]); 182 } 183 } 184 } 185 public static SID getServerSid(String server, 186 NtlmPasswordAuthentication auth) throws IOException { 187 DcerpcHandle handle = null; 188 LsaPolicyHandle policyHandle = null; 189 lsarpc.LsarDomainInfo info = new lsarpc.LsarDomainInfo(); 190 MsrpcQueryInformationPolicy2 rpc; 191 192 try { 193 handle = DcerpcHandle.getHandle("ncacn_np:" + server + 194 "[\\PIPE\\lsarpc]", auth); 195 policyHandle = new LsaPolicyHandle(handle, null, 0x02000000); 196 rpc = new MsrpcQueryInformationPolicy2(policyHandle, 197 (short)lsarpc.POLICY_INFO_ACCOUNT_DOMAIN, 198 info); 199 handle.sendrecv(rpc); 200 if (rpc.retval != 0) 201 throw new SmbException(rpc.retval, false); 202 203 return new SID(info.sid, 204 SID.SID_TYPE_DOMAIN, 205 (new UnicodeString(info.name, false)).toString(), 206 null, 207 false); 208 } finally { 209 if (handle != null) { 210 if (policyHandle != null) { 211 policyHandle.close(); 212 } 213 handle.close(); 214 } 215 } 216 } 217 218 int type; 219 String domainName = null; 220 String acctName = null; 221 String origin_server = null; 222 NtlmPasswordAuthentication origin_auth = null; 223 224 227 public SID(byte[] src, int si) { 228 revision = src[si++]; 229 sub_authority_count = src[si++]; 230 identifier_authority = new byte[6]; 231 System.arraycopy(src, si, identifier_authority, 0, 6); 232 si += 6; 233 if (sub_authority_count > 100) 234 throw new RuntimeException ( "Invalid SID" ); 235 sub_authority = new int[sub_authority_count]; 236 for (int i = 0; i < sub_authority_count; i++) { 237 sub_authority[i] = ServerMessageBlock.readInt4( src, si ); 238 si += 4; 239 } 240 } 241 245 public SID(String textual) throws SmbException { 246 StringTokenizer st = new StringTokenizer(textual, "-"); 247 if (st.countTokens() < 3 || !st.nextToken().equals("S")) 248 throw new SmbException("Bad textual SID format: " + textual); 250 251 this.revision = Byte.parseByte(st.nextToken()); 252 String tmp = st.nextToken(); 253 long id = 0; 254 if (tmp.startsWith("0x")) 255 id = Long.parseLong(tmp.substring(2), 16); 256 else 257 id = Long.parseLong(tmp); 258 259 this.identifier_authority = new byte[6]; 260 for (int i = 5; id > 0; i--) { 261 this.identifier_authority[i] = (byte) (id % 256); 262 id >>= 8; 263 } 264 265 this.sub_authority_count = (byte) st.countTokens(); 266 if (this.sub_authority_count > 0) { 267 this.sub_authority = new int[this.sub_authority_count]; 268 for (int i = 0; i < this.sub_authority_count; i++) 269 this.sub_authority[i] = (int)(Long.parseLong(st.nextToken()) & 0xFFFFFFFFL); 270 } 271 } 272 273 279 public SID(SID domsid, int rid) { 280 this.revision = domsid.revision; 281 this.identifier_authority = domsid.identifier_authority; 282 this.sub_authority_count = (byte)(domsid.sub_authority_count + 1); 283 this.sub_authority = new int[this.sub_authority_count]; 284 int i; 285 for (i = 0; i < domsid.sub_authority_count; i++) { 286 this.sub_authority[i] = domsid.sub_authority[i]; 287 } 288 this.sub_authority[i] = rid; 289 } 290 SID(rpc.sid_t sid, 291 int type, 292 String domainName, 293 String acctName, 294 boolean decrementAuthority) { 295 this.revision = sid.revision; 296 this.sub_authority_count = sid.sub_authority_count; 297 this.identifier_authority = sid.identifier_authority; 298 this.sub_authority = sid.sub_authority; 299 this.type = type; 300 this.domainName = domainName; 301 this.acctName = acctName; 302 303 if (decrementAuthority) { 304 this.sub_authority_count--; 305 this.sub_authority = new int[sub_authority_count]; 306 for (int i = 0; i < this.sub_authority_count; i++) { 307 this.sub_authority[i] = sid.sub_authority[i]; 308 } 309 } 310 } 311 312 public SID getDomainSid() { 313 return new SID(this, 314 SID_TYPE_DOMAIN, 315 this.domainName, 316 null, 317 getType() != SID_TYPE_DOMAIN); 318 } 319 public int getRid() { 320 if (getType() == SID_TYPE_DOMAIN) 321 throw new IllegalArgumentException ("This SID is a domain sid"); 322 return sub_authority[sub_authority_count - 1]; 323 } 324 325 344 public int getType() { 345 if (origin_server != null) 346 resolveWeak(); 347 return type; 348 } 349 350 354 public String getTypeText() { 355 if (origin_server != null) 356 resolveWeak(); 357 return SID_TYPE_NAMES[type]; 358 } 359 360 364 public String getDomainName() { 365 if (origin_server != null) 366 resolveWeak(); 367 if (type == SID_TYPE_UNKNOWN) { 368 String full = toString(); 369 return full.substring(0, full.length() - getAccountName().length() - 1); 370 } 371 return domainName; 372 } 373 374 379 public String getAccountName() { 380 if (origin_server != null) 381 resolveWeak(); 382 if (type == SID_TYPE_UNKNOWN) 383 return "" + sub_authority[sub_authority_count - 1]; 384 if (type == SID_TYPE_DOMAIN) 385 return ""; 386 return acctName; 387 } 388 389 public int hashCode() { 390 int hcode = identifier_authority[5]; 391 for (int i = 0; i < sub_authority_count; i++) { 392 hcode += 65599 * sub_authority[i]; 393 } 394 return hcode; 395 } 396 public boolean equals(Object obj) { 397 if (obj instanceof SID) { 398 SID sid = (SID)obj; 399 if (sid == this) 400 return true; 401 if (sid.sub_authority_count == sub_authority_count) { 402 int i = sub_authority_count; 403 while (i-- > 0) { 404 if (sid.sub_authority[i] != sub_authority[i]) { 405 return false; 406 } 407 } 408 for (i = 0; i < 6; i++) { 409 if (sid.identifier_authority[i] != identifier_authority[i]) { 410 return false; 411 } 412 } 413 414 return sid.revision == revision; 415 } 416 } 417 return false; 418 } 419 420 424 public String toString() { 425 String ret = "S-" + (revision & 0xFF) + "-"; 426 427 if (identifier_authority[0] != (byte)0 || identifier_authority[1] != (byte)0) { 428 ret += "0x"; 429 ret += Hexdump.toHexString(identifier_authority, 0, 6); 430 } else { 431 long shift = 0; 432 long id = 0; 433 for (int i = 5; i > 1; i--) { 434 id += (identifier_authority[i] & 0xFFL) << shift; 435 shift += 8; 436 } 437 ret += id; 438 } 439 440 for (int i = 0; i < sub_authority_count ; i++) 441 ret += "-" + (sub_authority[i] & 0xFFFFFFFFL); 442 443 return ret; 444 } 445 446 462 public String toDisplayString() { 463 if (origin_server != null) 464 resolveWeak(); 465 if (domainName != null) { 466 String str; 467 468 if (type == SID_TYPE_DOMAIN) { 469 str = domainName; 470 } else if (type == SID_TYPE_WKN_GRP || 471 domainName.equals("BUILTIN")) { 472 if (type == SID_TYPE_UNKNOWN) { 473 str = toString(); 474 } else { 475 str = acctName; 476 } 477 } else { 478 str = domainName + "\\" + acctName; 479 } 480 481 return str; 482 } 483 return toString(); 484 } 485 486 496 public void resolve(String authorityServerName, 497 NtlmPasswordAuthentication auth) throws IOException { 498 SID[] sids = new SID[1]; 499 sids[0] = this; 500 SID.resolveSids(authorityServerName, auth, sids); 501 } 502 503 void resolveWeak() { 504 if (origin_server != null) { 505 try { 506 resolve(origin_server, origin_auth); 507 } catch(IOException ioe) { 508 } finally { 509 origin_server = null; 510 origin_auth = null; 511 } 512 } 513 } 514 515 static SID[] getGroupMemberSids0(DcerpcHandle handle, 516 SamrDomainHandle domainHandle, 517 SID domsid, 518 int rid, 519 int flags) throws IOException { 520 SamrAliasHandle aliasHandle = null; 521 lsarpc.LsarSidArray sidarray = new lsarpc.LsarSidArray(); 522 MsrpcGetMembersInAlias rpc = null; 523 524 try { 525 aliasHandle = new SamrAliasHandle(handle, domainHandle, 0x0002000c, rid); 526 rpc = new MsrpcGetMembersInAlias(aliasHandle, sidarray); 527 handle.sendrecv(rpc); 528 if (rpc.retval != 0) 529 throw new SmbException(rpc.retval, false); 530 SID[] sids = new SID[rpc.sids.num_sids]; 531 532 String origin_server = handle.getServer(); 533 NtlmPasswordAuthentication origin_auth = 534 (NtlmPasswordAuthentication)handle.getPrincipal(); 535 536 for (int i = 0; i < sids.length; i++) { 537 sids[i] = new SID(rpc.sids.sids[i].sid, 538 0, 539 null, 540 null, 541 false); 542 sids[i].origin_server = origin_server; 543 sids[i].origin_auth = origin_auth; 544 } 545 if (sids.length > 0 && (flags & SID_FLAG_RESOLVE_SIDS) != 0) { 546 SID.resolveSids(origin_server, origin_auth, sids); 547 } 548 return sids; 549 } finally { 550 if (aliasHandle != null) { 551 aliasHandle.close(); 552 } 553 } 554 } 555 556 public SID[] getGroupMemberSids(String authorityServerName, 557 NtlmPasswordAuthentication auth, 558 int flags) throws IOException { 559 if (type != SID_TYPE_DOM_GRP && type != SID_TYPE_ALIAS) 560 return new SID[0]; 561 562 DcerpcHandle handle = null; 563 SamrPolicyHandle policyHandle = null; 564 SamrDomainHandle domainHandle = null; 565 SID domsid = getDomainSid(); 566 567 try { 568 handle = DcerpcHandle.getHandle("ncacn_np:" + authorityServerName + 569 "[\\PIPE\\samr]", auth); 570 policyHandle = new SamrPolicyHandle(handle, authorityServerName, 0x00000030); 571 domainHandle = new SamrDomainHandle(handle, policyHandle, 0x00000200, domsid); 572 return SID.getGroupMemberSids0(handle, 573 domainHandle, 574 domsid, 575 getRid(), 576 flags); 577 } finally { 578 if (handle != null) { 579 if (policyHandle != null) { 580 if (domainHandle != null) { 581 domainHandle.close(); 582 } 583 policyHandle.close(); 584 } 585 handle.close(); 586 } 587 } 588 } 589 590 612 static Map getLocalGroupsMap(String authorityServerName, 613 NtlmPasswordAuthentication auth, 614 int flags) throws IOException { 615 SID domsid = SID.getServerSid(authorityServerName, auth); 616 DcerpcHandle handle = null; 617 SamrPolicyHandle policyHandle = null; 618 SamrDomainHandle domainHandle = null; 619 samr.SamrSamArray sam = new samr.SamrSamArray(); 620 MsrpcEnumerateAliasesInDomain rpc; 621 622 try { 623 handle = DcerpcHandle.getHandle("ncacn_np:" + authorityServerName + 624 "[\\PIPE\\samr]", auth); 625 policyHandle = new SamrPolicyHandle(handle, authorityServerName, 0x02000000); 626 domainHandle = new SamrDomainHandle(handle, policyHandle, 0x02000000, domsid); 627 rpc = new MsrpcEnumerateAliasesInDomain(domainHandle, 0xFFFF, sam); 628 handle.sendrecv(rpc); 629 if (rpc.retval != 0) 630 throw new SmbException(rpc.retval, false); 631 632 Map map = new HashMap(); 633 634 for (int ei = 0; ei < rpc.sam.count; ei++) { 635 samr.SamrSamEntry entry = rpc.sam.entries[ei]; 636 637 SID[] mems = SID.getGroupMemberSids0(handle, 638 domainHandle, 639 domsid, 640 entry.idx, 641 flags); 642 SID groupSid = new SID(domsid, entry.idx); 643 groupSid.type = SID_TYPE_ALIAS; 644 groupSid.domainName = domsid.getDomainName(); 645 groupSid.acctName = (new UnicodeString(entry.name, false)).toString(); 646 647 for (int mi = 0; mi < mems.length; mi++) { 648 ArrayList groups = (ArrayList)map.get(mems[mi]); 649 if (groups == null) { 650 groups = new ArrayList(); 651 map.put(mems[mi], groups); 652 } 653 if (!groups.contains(groupSid)) 654 groups.add(groupSid); 655 } 656 } 657 658 return map; 659 } finally { 660 if (handle != null) { 661 if (policyHandle != null) { 662 if (domainHandle != null) { 663 domainHandle.close(); 664 } 665 policyHandle.close(); 666 } 667 handle.close(); 668 } 669 } 670 } 671 } 672 673 | Popular Tags |