public static DsObjectInformation Get(string domain, string object_class) { var schema_class = DirectoryServiceUtils.GetSchemaClass(domain, object_class); if (schema_class == null) { return(null); } var ret = new DsObjectInformation(); ret.SchemaClass = schema_class; var classes = DirectoryServiceUtils.GetSchemaClasses(domain, object_class, true); ret.InferiorClasses = schema_class.PossibleInferiors.Select(i => DirectoryServiceUtils.GetSchemaClass(domain, i)).ToList(); ret.Attributes = classes.SelectMany(c => c.Attributes.Select(a => DirectoryServiceUtils.GetSchemaAttribute(domain, a.Name))).Distinct().ToList(); ret.ExtendedRights = DirectoryServiceUtils.GetExtendedRights(domain, schema_class.SchemaId).ToList(); ret.ObjectTypes = new Dictionary <Guid, IDirectoryServiceObjectTree>(); ret.ObjectTypes[ret.SchemaClass.SchemaId] = ret.SchemaClass; AddObjectTypes(ret.ObjectTypes, ret.InferiorClasses); AddObjectTypes(ret.ObjectTypes, ret.Attributes); AddObjectTypes(ret.ObjectTypes, ret.ExtendedRights); return(ret); }
private void GetAccessCheckResult(string dn, string name, bool is_deleted, DsObjectInformation obj_info, SecurityDescriptor sd, Sid object_sid) { for (int i = 0; i < _context.Count; ++i) { var ctx = _context[i]; var token_info = _token_info[i]; var granted_access_no_type = AccessCheckSingle(ctx, sd, object_sid, null); var granted_access = AccessCheckSingle(ctx, sd, object_sid, obj_info.SchemaClass); AccessMask max_granted_access = granted_access_no_type | granted_access; var rights_results = new List <DsObjectTypeAccessCheckResult <DirectoryServiceExtendedRight> >(); var class_results = new List <DsObjectTypeAccessCheckResult <DirectoryServiceSchemaClass> >(); var attr_results = new List <DsObjectTypeAccessCheckResult <DirectoryServiceSchemaAttribute> >(); MapResults(AccessCheck(ctx, sd, object_sid, obj_info.GetInferiorClasses()), obj_info, rights_results, class_results, attr_results, ref max_granted_access); MapResults(AccessCheck(ctx, sd, object_sid, obj_info.GetExtendedRights()), obj_info, rights_results, class_results, attr_results, ref max_granted_access); MapResults(AccessCheck(ctx, sd, object_sid, obj_info.GetAttributes()), obj_info, rights_results, class_results, attr_results, ref max_granted_access); if (max_granted_access.IsEmpty && !AllowEmptyAccess) { continue; } WriteObject(new DsObjectAccessCheckResult(dn, name, obj_info.SchemaClass, is_deleted, Domain, granted_access, granted_access_no_type, max_granted_access, rights_results.Where(r => r.Object.IsPropertySet), rights_results.Where(r => r.Object.IsControl), rights_results.Where(r => r.Object.IsValidatedWrite), class_results, attr_results, sd, token_info)); } }
private void MapResults(IEnumerable <AuthZAccessCheckResult> results, DsObjectInformation obj_info, List <DsObjectTypeAccessCheckResult <DirectoryServiceExtendedRight> > rights, List <DsObjectTypeAccessCheckResult <DirectoryServiceSchemaClass> > classes, List <DsObjectTypeAccessCheckResult <DirectoryServiceSchemaAttribute> > attrs, ref AccessMask max_granted_access) { foreach (var result in results.Where(r => r.Level > 0)) { if (result.GrantedAccess.IsEmpty && !AllowEmptyAccess) { continue; } if (!obj_info.ObjectTypes.TryGetValue(result.ObjectType, out IDirectoryServiceObjectTree value)) { continue; } max_granted_access |= result.GrantedAccess; if (value is DirectoryServiceExtendedRight right) { rights.Add(new DsObjectTypeAccessCheckResult <DirectoryServiceExtendedRight>(right, result)); } else if (value is DirectoryServiceSchemaClass schema_class) { classes.Add(new DsObjectTypeAccessCheckResult <DirectoryServiceSchemaClass>(schema_class, result)); } else if (value is DirectoryServiceSchemaAttribute attr_class) { attrs.Add(new DsObjectTypeAccessCheckResult <DirectoryServiceSchemaAttribute>(attr_class, result)); } } }
private void RunAccessCheck(DirectoryEntry root, string filter, bool recurse, bool recurse_subtree, int current_depth) { if (current_depth < 0) { return; } SearchScope scope = recurse ? SearchScope.OneLevel : (recurse_subtree ? SearchScope.Subtree : SearchScope.Base); foreach (var result in FindAllDirectoryEntries(root, scope, IncludeDeleted, filter, kDistinguishedName, kObjectClass, kStructuralObjectClass, kNTSecurityDescriptor, kObjectSid, kName, kIsDeleted)) { if (Stopping) { return; } string dn = GetPropertyValue <string>(result, kDistinguishedName); if (string.IsNullOrWhiteSpace(dn)) { WriteWarning($"Couldn't get DN for '{result.Path}'"); continue; } if (!IncludePath(dn)) { continue; } WriteProgress($"Checking {dn}"); string name = GetPropertyValue <string>(result, kName); var sd = GetObjectSecurityDescriptor(result); if (sd == null) { WriteWarning($"Couldn't get security descriptor '{dn}'"); continue; } string obj_class = GetObjectClass(result); if (string.IsNullOrWhiteSpace(obj_class)) { WriteWarning($"Couldn't get object class for '{dn}'"); continue; } var obj_info = _cached_info.GetOrAdd(obj_class, n => DsObjectInformation.Get(Domain, n)); if (obj_info == null) { WriteWarning($"Couldn't get object information for '{dn}'"); continue; } string[] structural_obj_classes = GetPropertyValues <string>(result, kStructuralObjectClass); string[] obj_classes = GetPropertyValues <string>(result, kObjectClass); List <DsObjectInformation> dynamic_aux_classes = new List <DsObjectInformation>(); if (obj_classes.Length > structural_obj_classes.Length) { foreach (var dynamic_aux_class in obj_classes.Where(c => !obj_info.ClassNames.Contains(c)).Distinct()) { dynamic_aux_classes.Add(_cached_info.GetOrAdd(dynamic_aux_class, n => DsObjectInformation.Get(Domain, n))); } } GetAccessCheckResult(dn, name, GetIsDeleted(result), obj_info, dynamic_aux_classes, sd, GetObjectSid(result)); } if (Stopping) { return; } if (recurse) { foreach (DirectoryEntry entry in root.Children) { if (Stopping) { return; } using (entry) { RunAccessCheck(entry, filter, recurse, recurse_subtree, current_depth - 1); } } } }