public EffectiveAccess(string path, string targetMachine, RawSecurityDescriptor shareSD, SecurityIdentifier userSid, SecurityIdentifier deviceSid, ClaimValueDictionary userClaims, ClaimValueDictionary deviceClaims, GroupsCollection userGroups, GroupsCollection deviceGroups) { if (string.IsNullOrEmpty(targetMachine) && shareSD != null) { throw new ArgumentException("targetMachine must be value when shareSD is not-empty", "targetMachine"); } handle = NativeMethods.CreateFile(path, NativeMethods.FileAccess.GenericRead, NativeMethods.FileShare.Read | NativeMethods.FileShare.Write | NativeMethods.FileShare.Delete, IntPtr.Zero, NativeMethods.FileMode.OpenExisting, NativeMethods.FileFlagAttrib.BackupSemantics, IntPtr.Zero); if (handle.IsInvalid) { throw new Win32Exception(Marshal.GetLastWin32Error()); } this.targetMachine = targetMachine; this.shareSD = shareSD; this.userSid = userSid; this.deviceSid = deviceSid; this.userClaims = userClaims; this.deviceClaims = deviceClaims; this.userGroups = userGroups; this.deviceGroups = deviceGroups; }
static void Main(string[] args) { const string PATH_PREFIX = "/path:"; const string TARGET_PREFIX = "/targetMachine:"; const string SHARESD_PREFIX = "/shareSD:"; const string USER_PREFIX = "/user:"******"/usergroup:"; const string USER_CLAIM_PREFIX = "/userclaim:"; const string DEVICE_PREFIX = "/device:"; const string DEVICE_GROUP_PREFIX = "/devicegroup:"; const string DEVICE_CLAIM_PREFIX = "/deviceclaim:"; const string CLAIM_PREFIX_REGEX = "^/(?<claimdefinitiontype>user|device)claim:"; const string ATTRIBUTE_REGEX = @"\((?<id>[\w]+),(?<type>[\w]+),(?<value>.+)\)"; string cmdLnPrefixInProcess = null; string cmdLnParam = null; bool showUsageAndExit = (args.Length == 0); try { foreach (var arg in args) { cmdLnParam = arg; if (arg.StartsWith(PATH_PREFIX, StringComparison.Ordinal)) { cmdLnPrefixInProcess = PATH_PREFIX; if (path == null) { path = arg.Substring(PATH_PREFIX.Length); } else { Helper.ReportDuplicateCmdLnParam(arg); } continue; } if (arg.StartsWith(TARGET_PREFIX, StringComparison.Ordinal)) { cmdLnPrefixInProcess = TARGET_PREFIX; if (targetMachine == null) { targetMachine = arg.Substring(TARGET_PREFIX.Length); } else { Helper.ReportDuplicateCmdLnParam(arg); } continue; } if (arg.StartsWith(SHARESD_PREFIX, StringComparison.Ordinal)) { cmdLnPrefixInProcess = SHARESD_PREFIX; if (shareSD == null) { shareSD = new RawSecurityDescriptor(arg.Substring(SHARESD_PREFIX.Length)); } else { Helper.ReportDuplicateCmdLnParam(arg); } continue; } if (arg.StartsWith(USER_PREFIX, StringComparison.Ordinal)) { cmdLnPrefixInProcess = USER_PREFIX; if (userSid == null) { try { userSid = Helper.GetSidForObject(arg.Substring(USER_PREFIX.Length)); } catch (IdentityNotMappedException) { Helper.ReportIgnoredAccount(arg.Substring(USER_PREFIX.Length), arg); } } else { Helper.ReportDuplicateCmdLnParam(arg); } continue; } if (arg.StartsWith(DEVICE_PREFIX, StringComparison.Ordinal)) { cmdLnPrefixInProcess = USER_PREFIX; if (deviceSid == null) { try { deviceSid = Helper.GetSidForObject(arg.Substring(DEVICE_PREFIX.Length), true); } catch (IdentityNotMappedException) { Helper.ReportIgnoredAccount(arg.Substring(DEVICE_PREFIX.Length), arg); } } else { Helper.ReportDuplicateCmdLnParam(arg); } continue; } if (arg.StartsWith(USER_CLAIM_PREFIX, StringComparison.Ordinal) || arg.StartsWith(DEVICE_CLAIM_PREFIX, StringComparison.Ordinal)) { Match result = Regex.Match(arg, CLAIM_PREFIX_REGEX + "(?<claiminfo>" + ATTRIBUTE_REGEX + ")"); if (result.Success) { bool userClaimDefinitionType = result.Groups["claimdefinitiontype"].Value == "user"; cmdLnPrefixInProcess = userClaimDefinitionType ? USER_CLAIM_PREFIX : DEVICE_CLAIM_PREFIX; string claimInfo = result.Groups["claiminfo"].Value; string claimID = result.Groups["id"].Value; string valueType = result.Groups["type"].Value; string value = result.Groups["value"].Value; ClaimValueDictionary claimsColln = userClaimDefinitionType ? userClaims : deviceClaims; try { if (claimsColln.ContainsKey(claimID)) { Helper.ReportDuplicateClaim(claimID, arg); } else { claimsColln.Add(claimID, new ClaimValue( (ClaimValueType) Enum.Parse(typeof(ClaimValueType), valueType), value)); } } catch (BadValueException e) { Helper.LogWarning("Ignoring claim - "); Console.Write(claimInfo); Helper.LogWarning(string.Format(CultureInfo.CurrentCulture, ". {0}", e.Message), true); } catch (Exception e) { Debug.Assert(e.GetType() == typeof(ArgumentException)); Helper.LogWarning("Ignoring claim - "); Console.Write(claimInfo); Helper.LogWarning(string.Format(CultureInfo.CurrentCulture, ", with unrecognized value type - {0}", valueType), true); } } else { Helper.LogWarning("Ignoring ill-formatted claim specification in parameter: "); Console.WriteLine(arg); } continue; } if (arg.StartsWith(USER_GROUP_PREFIX, StringComparison.Ordinal) || arg.StartsWith(DEVICE_GROUP_PREFIX, StringComparison.Ordinal)) { bool groupTypeUser = arg.StartsWith(USER_GROUP_PREFIX, StringComparison.Ordinal); string groupInfo = arg.Substring(groupTypeUser ? USER_GROUP_PREFIX.Length : DEVICE_GROUP_PREFIX.Length); cmdLnPrefixInProcess = groupTypeUser ? USER_GROUP_PREFIX : DEVICE_GROUP_PREFIX; GroupsCollection groupsColln = groupTypeUser ? userGroups : deviceGroups; try { groupsColln.Add(Helper.GetSidForObject(groupInfo, !groupTypeUser)); } catch (IdentityNotMappedException) { Helper.ReportIgnoredAccount(groupInfo, arg); } continue; } Helper.LogWarning("Ignoring unrecognized parameter: "); Console.WriteLine(arg); } } catch (ArgumentException e) { showUsageAndExit = true; switch (cmdLnPrefixInProcess) { case USER_PREFIX: case USER_GROUP_PREFIX: case DEVICE_PREFIX: case DEVICE_GROUP_PREFIX: { Helper.LogError("Invalid string SID in parameter: "); Helper.LogWarning(cmdLnParam, true); break; } case SHARESD_PREFIX: { Helper.LogError("The SDDL form of the security descriptor is invalid in parameter: "); Helper.LogWarning(cmdLnParam, true); break; } default: { showUsageAndExit = false; Console.WriteLine(e.Message); break; } } } catch (Exception e) { showUsageAndExit = true; Console.WriteLine(e.Message); return; } finally { if (!showUsageAndExit) { bool missingRequiredParam = (userSid == null); if (string.IsNullOrEmpty(path)) { missingRequiredParam = true; } else if (!Directory.Exists(path) && !File.Exists(path)) { Helper.LogError("Could not find specified resource: "); Helper.LogWarning(path, true); // // Don't report more than 1 errors // missingRequiredParam = false; } else if (deviceClaims.Count != 0 && deviceSid == null) { Helper.LogWarning("Device claims ignored since no valid device account was specified"); } else if (shareSD != null && string.IsNullOrEmpty(targetMachine)) { Helper.LogError("Share's Security descriptor(/shareSD) specified without specifying " + "/targetMachine.", true); showUsageAndExit = true; } if (missingRequiredParam) { Helper.LogError("Required parameters missing", true); showUsageAndExit = true; } } } if (showUsageAndExit) { Console.WriteLine(CmdLnUsage, Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase)); return; } try { if (string.IsNullOrEmpty(targetMachine)) { targetMachine = "localhost"; } var effPerm = new EffectiveAccess(path, targetMachine, shareSD, userSid, deviceSid, userClaims, deviceClaims, userGroups, deviceGroups); effPerm.Evaluate(); effPerm.GenerateReport(); } catch (Win32Exception win32Exp) { Helper.LogError("Win32 exception: "); Helper.LogWarning(win32Exp.Message); } catch (Exception e) { Helper.LogError("Unhandled exception: "); Helper.LogWarning(e.Message); } }