internal void GetComputerShares(string computer) { // find the shares HostShareInfo[] hostShareInfos = GetHostShareInfo(computer); BlockingStaticTaskScheduler treeTaskScheduler = SnaffCon.GetTreeTaskScheduler(); foreach (HostShareInfo hostShareInfo in hostShareInfos) { string shareName = GetShareName(hostShareInfo, computer); if (!String.IsNullOrWhiteSpace(shareName)) { bool matched = false; // classify them foreach (ClassifierRule classifier in MyOptions.ShareClassifiers) { ShareClassifier shareClassifier = new ShareClassifier(classifier); if (shareClassifier.ClassifyShare(shareName)) { matched = true; break; } } // by default all shares should go on to TreeWalker unless the classifier pulls them out. // send them to TreeWalker if (!matched) { if (IsShareReadable(shareName)) { ShareResult shareResult = new ShareResult() { Listable = true, SharePath = shareName }; Mq.ShareResult(shareResult); Mq.Info("Creating a TreeWalker task for " + shareResult.SharePath); treeTaskScheduler.New(() => { try { new TreeWalker(shareResult.SharePath); } catch (Exception e) { Mq.Trace(e.ToString()); } }); } } } } }
internal void GetComputerShares(string computer) { // find the shares HostShareInfo[] hostShareInfos = GetHostShareInfo(computer); foreach (HostShareInfo hostShareInfo in hostShareInfos) { string shareName = GetShareName(hostShareInfo, computer); if (!String.IsNullOrWhiteSpace(shareName)) { bool matched = false; // SYSVOL and NETLOGON shares are replicated so they have special logic - do not use Classifiers for these switch (hostShareInfo.shi1_netname.ToUpper()) { case "SYSVOL": if (MyOptions.ScanSysvol == true) { // leave matched as false so that we don't suppress the TreeWalk for the first SYSVOL replica we see // toggle the flag so that any other shares replica will be skipped MyOptions.ScanSysvol = false; break; } matched = true; break; case "NETLOGON": if (MyOptions.ScanNetlogon == true) { // same as SYSVOL above MyOptions.ScanNetlogon = false; break; } matched = true; break; default: // classify them foreach (ClassifierRule classifier in MyOptions.ShareClassifiers) { ShareClassifier shareClassifier = new ShareClassifier(classifier); if (shareClassifier.ClassifyShare(shareName)) { matched = true; break; } } break; } // by default all shares should go on to TreeWalker unless the classifier pulls them out. // send them to TreeWalker if (!matched) { if (IsShareReadable(shareName)) { ShareResult shareResult = new ShareResult() { Listable = true, SharePath = shareName }; Mq.ShareResult(shareResult); Mq.Info("Creating a TreeWalker task for " + shareResult.SharePath); TreeTaskScheduler.New(() => { try { TreeWalker.WalkTree(shareResult.SharePath); } catch (Exception e) { Mq.Error("Exception in TreeWalker task for share " + shareResult.SharePath); Mq.Error(e.ToString()); } }); } } } } }
internal void GetComputerShares(string computer) { // find the shares HostShareInfo[] hostShareInfos = GetHostShareInfo(computer); foreach (HostShareInfo hostShareInfo in hostShareInfos) { // skip IPC$ and PRINT$ shares for #OPSEC!!! List <string> neverScan = new List <string> { "ipc$", "print$" }; if (neverScan.Contains(hostShareInfo.shi1_netname.ToLower())) { continue; } string shareName = GetShareName(hostShareInfo, computer); if (!String.IsNullOrWhiteSpace(shareName)) { bool matched = false; // SYSVOL and NETLOGON shares are replicated so they have special logic - do not use Classifiers for these switch (hostShareInfo.shi1_netname.ToUpper()) { case "SYSVOL": if (MyOptions.ScanSysvol == true) { // Leave matched as false so that we don't suppress the TreeWalk for the first SYSVOL replica we see. // Toggle the flag so that any other shares replica will be skipped MyOptions.ScanSysvol = false; break; } matched = true; break; case "NETLOGON": if (MyOptions.ScanNetlogon == true) { // Same logic as SYSVOL above MyOptions.ScanNetlogon = false; break; } matched = true; break; default: // classify them foreach (ClassifierRule classifier in MyOptions.ShareClassifiers) { ShareClassifier shareClassifier = new ShareClassifier(classifier); if (shareClassifier.ClassifyShare(shareName)) { // in this instance 'matched' means 'matched a discard rule, so don't send to treewalker'. matched = true; break; } } break; } // by default all shares should go on to TreeWalker unless the classifier pulls them out. // send them to TreeWalker if (!matched) { // At least one classifier was matched so we will return this share to the results ShareResult shareResult = new ShareResult() { Listable = true, SharePath = shareName, ShareComment = hostShareInfo.shi1_remark.ToString() }; // Try to find this computer+share in the list of DFS targets /* * foreach (DFSShare dfsShare in MyOptions.DfsShares) * { * ///TODO: Add some logic to match cases where short hostnames is used in DFS target list * if (dfsShare.RemoteServerName.Equals(computer, StringComparison.OrdinalIgnoreCase) && * dfsShare.Name.Equals(hostShareInfo.shi1_netname, StringComparison.OrdinalIgnoreCase)) * { * // why the not operator? if (!MyOptions.DfsNamespacePaths.Contains(dfsShare.DfsNamespacePath)) * if (MyOptions.DfsNamespacePaths.Contains(dfsShare.DfsNamespacePath)) * { * // remove the namespace path to make sure we don't kick it off again. * MyOptions.DfsNamespacePaths.Remove(dfsShare.DfsNamespacePath); * // sub out the \\computer\share path for the dfs namespace path. this makes sure we hit the most efficient endpoint. * shareName = dfsShare.DfsNamespacePath; * } * else // if that dfs namespace has already been removed from our list, skip further scanning of that share. * { * skip = true; * } * * // Found DFS target matching this computer+share - no further comparisons needed * break; * } * } */ // If this path can be accessed via DFS if (MyOptions.DfsSharesDict.ContainsKey(shareName)) { string dfsUncPath = MyOptions.DfsSharesDict[shareName]; Mq.Degub(String.Format("Matched host path {0} to DFS {1}", shareName, dfsUncPath)); // and if we haven't already scanned this share if (MyOptions.DfsNamespacePaths.Contains(dfsUncPath)) { Mq.Degub(String.Format("Will scan {0} using DFS referral instead of explicit host", dfsUncPath)); // sub out the \\computer\share path for the dfs namespace path. this makes sure we hit the most efficient endpoint. shareResult.SharePath = dfsUncPath; // remove the namespace path to make sure we don't kick it off again. MyOptions.DfsNamespacePaths.Remove(dfsUncPath); } else // if that dfs path has already been removed from our list, skip further scanning of that share. { // Do we want to report a gray share result for these? I think not. // Mq.ShareResult(shareResult); break; } } // If the share is readable then dig deeper. if (IsShareReadable(shareResult.SharePath)) { // Share is readable, report as green (the old default/min of the Triage enum ) shareResult.Triage = Triage.Green; try { DirectoryInfo dirInfo = new DirectoryInfo(shareResult.SharePath); //EffectivePermissions.RwStatus rwStatus = effectivePermissions.CanRw(dirInfo); shareResult.RootModifyable = false; shareResult.RootWritable = false; shareResult.RootReadable = true; /* * if (rwStatus.CanWrite || rwStatus.CanModify) * { * triage = Triage.Yellow; * } */ } catch (System.UnauthorizedAccessException e) { Mq.Error("Failed to get permissions on " + shareResult.SharePath); } if (MyOptions.ScanFoundShares) { Mq.Trace("Creating a TreeWalker task for " + shareResult.SharePath); TreeTaskScheduler.New(() => { try { TreeWalker.WalkTree(shareResult.SharePath); } catch (Exception e) { Mq.Error("Exception in TreeWalker task for share " + shareResult.SharePath); Mq.Error(e.ToString()); } }); } Mq.ShareResult(shareResult); } else if (MyOptions.LogDeniedShares == true) { Mq.ShareResult(shareResult); } } } } }