/// <summary>
        /// Parse a PermittedLogonTimes byte array into a LogonTimes object.
        /// </summary>
        /// <param name="times">Byte array of UTC logon times.</param>
        /// <returns>A LogonTimes object of the given permitted times.</returns>
        public static LogonTimes PermittedLogonTimes(byte[] times)
        {
            if (times == null)
                return null;//All?

            var logonTimes = new LogonTimes();

            //Each day gets 3 bytes of hour flags, make sure the array is long enough to loop through all of them.
            Array.Resize<byte>(ref times, 3 * 7);
            for (var i = 0; i < 3 * 7; i += 3)
            {
                byte[] bytes = { times[i + 0], times[i + 1], times[i + 2], 0 };//Aggregate all of the hour flags.
                if (!BitConverter.IsLittleEndian)//Make sure they bytes are in the proper order to make into one large set of flags.
                    Array.Reverse(bytes);
                var bits = BitConverter.ToInt32(bytes, 0);//Convert the 3 bytes of flags into one set of flags.
                if (bits == 0)//nothing on this day
                    continue;

                //0, 3, 6, 9, 12, 15, 18, 21
                var day = (DayOfWeek)(i / 3);
                for (var j = 0; j < 24; j++)
                {
                    if ((bits & 1 << j) > 0)
                        logonTimes.Add(day, LogonTimeUnit.Hours, (uint)j);
                }
            }

            return logonTimes;
        }
Пример #2
0
        /// <summary>
        /// Parse a PermittedLogonTimes byte array into a LogonTimes object.
        /// </summary>
        /// <param name="times">Byte array of UTC logon times.</param>
        /// <returns>A LogonTimes object of the given permitted times.</returns>
        public static LogonTimes PermittedLogonTimes(byte[] times)
        {
            if (times == null)
            {
                return(null);//All?
            }
            var logonTimes = new LogonTimes();

            //Each day gets 3 bytes of hour flags, make sure the array is long enough to loop through all of them.
            Array.Resize <byte>(ref times, 3 * 7);
            for (var i = 0; i < 3 * 7; i += 3)
            {
                byte[] bytes = { times[i + 0], times[i + 1], times[i + 2], 0 }; //Aggregate all of the hour flags.
                if (!BitConverter.IsLittleEndian)                               //Make sure they bytes are in the proper order to make into one large set of flags.
                {
                    Array.Reverse(bytes);
                }
                var bits = BitConverter.ToInt32(bytes, 0); //Convert the 3 bytes of flags into one set of flags.
                if (bits == 0)                             //nothing on this day
                {
                    continue;
                }

                //0, 3, 6, 9, 12, 15, 18, 21
                var day = (DayOfWeek)(i / 3);
                for (var j = 0; j < 24; j++)
                {
                    if ((bits & 1 << j) > 0)
                    {
                        logonTimes.Add(day, LogonTimeUnit.Hours, (int)(uint)j);
                    }
                }
            }

            return(logonTimes);
        }
Пример #3
0
        internal static IList <Claim> GetClaims(this UserPrincipal user, IList <string> claimTypes, SerializationFormat serializationFormat = SerializationFormat.Json)
        {
            claimTypes = claimTypes ?? new List <string>();

            if (user == null)
            {
                throw new ArgumentNullException("user");
            }
            if (user.Guid.HasValue == false)
            {
                throw new MissingFieldException(Resource.MissingUserPrincipalGuid);
            }
            if (user.Sid == null)
            {
                throw new MissingFieldException(Resource.MissingUserPrincipalSid);
            }

            var claims = new List <Claim>();

            //Generate here from the SameAccountName instead of passing it through?
            //claims.Add(new Claim(ClaimTypes.Name, user.Name, ClaimValueTypes.String));

            //This is required for ASP.NET Identity, it should be a value unique to each user. https://technet.microsoft.com/en-us/library/cc961625.aspx SID can change "sometimes", Guid should never change.
            claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Guid.Value.ToString(), ClaimValueTypes.String));
            claims.Add(new Claim(ClaimTypes.PrimarySid, user.Sid.Value, ClaimValueTypes.Sid));
            claims.Add(new Claim(ClaimTypesAD.Guid, user.Guid.Value.ToString(), ClaimValueTypes.String));

            var securityGroups = user.GetAuthorizationGroups().Cast <GroupPrincipal>();

            claims = claims.Union(securityGroups.Select(_ => {
                //TODO: Need a better way to get netbios domain from DistinguishedName
                var domain = Owin.Security.ActiveDirectoryLDAP.DomainCredentialConfig.DomainCredentials.FirstOrDefault(d => _ != null && !String.IsNullOrEmpty(_.DistinguishedName) && _.DistinguishedName.EndsWith(d.Container, StringComparison.OrdinalIgnoreCase));
                if (domain != null)
                {
                    return(new Claim(ClaimsIdentity.DefaultRoleClaimType, String.Format(CultureInfo.InvariantCulture, @"{0}\{1}", domain.NetBIOS, _.SamAccountName), ClaimValueTypes.String));
                }
                return(null);
            }).Where(_ => _ != null)).ToList();//will these always be security groups?

            //Is the first group the primary group? It seems so in testing but I'm not sure if that can be relied on.
            //var primaryGroup = securityGroups.FirstOrDefault();
            //if (primaryGroup != null)
            //    claims.Add(new Claim(ClaimTypes.PrimaryGroupSid, primaryGroup.Sid.Value, ClaimValueTypes.Sid));

            if (claimTypes.Contains(ClaimTypes.GroupSid) && securityGroups.Any())
            {
                claims.AddRange(securityGroups.Select(_ => new Claim(ClaimTypes.GroupSid, _.Sid.Value, ClaimValueTypes.Sid)));// Union?
            }
            if (claimTypes.Contains(ClaimTypesAD.BadLogonCount))
            {
                claims.Add(new Claim(ClaimTypesAD.BadLogonCount, user.BadLogonCount.ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Integer32));//can this be set via a webapp? part of ValidateCredentials?
            }
            if (claimTypes.Contains(ClaimTypesAD.Enabled) /* && user.Enabled.HasValue*/)
            {
                claims.Add(new Claim(ClaimTypesAD.Enabled, (user.Enabled ?? false).ToString(), ClaimValueTypes.Boolean));//default? is a null value considered disabled?
            }
            if (claimTypes.Contains(ClaimTypesAD.LockedOut))
            {
                claims.Add(new Claim(ClaimTypesAD.LockedOut, user.IsAccountLockedOut().ToString(), ClaimValueTypes.Boolean));
            }
            if (claimTypes.Contains(ClaimTypesAD.SmartcardLogonRequired))
            {
                claims.Add(new Claim(ClaimTypesAD.SmartcardLogonRequired, user.SmartcardLogonRequired.ToString(), ClaimValueTypes.Boolean));//Deny? How could we handle this.
            }
            if (claimTypes.Contains(ClaimTypesAD.Description) && !String.IsNullOrEmpty(user.Description))
            {
                claims.Add(new Claim(ClaimTypesAD.Description, user.Description, ClaimValueTypes.String));//job title?
            }
            if (claimTypes.Contains(ClaimTypesAD.DisplayName) && !String.IsNullOrEmpty(user.DisplayName))
            {
                claims.Add(new Claim(ClaimTypesAD.DisplayName, user.DisplayName, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypesAD.DistinguishedName) && !String.IsNullOrEmpty(user.DistinguishedName))
            {
                claims.Add(new Claim(ClaimTypesAD.DistinguishedName, user.DistinguishedName, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypes.Email) && !String.IsNullOrEmpty(user.EmailAddress))
            {
                claims.Add(new Claim(ClaimTypes.Email, user.EmailAddress, ClaimValueTypes.Email));
            }
            if (claimTypes.Contains(ClaimTypesAD.EmployeeId) && !String.IsNullOrEmpty(user.EmployeeId))
            {
                claims.Add(new Claim(ClaimTypesAD.EmployeeId, user.EmployeeId, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypes.GivenName) && !String.IsNullOrEmpty(user.GivenName))
            {
                claims.Add(new Claim(ClaimTypes.GivenName, user.GivenName, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypesAD.HomeDirectory) && !String.IsNullOrEmpty(user.HomeDirectory))
            {
                claims.Add(new Claim(ClaimTypesAD.HomeDirectory, user.HomeDirectory, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypesAD.HomeDrive) && !String.IsNullOrEmpty(user.HomeDrive))
            {
                claims.Add(new Claim(ClaimTypesAD.HomeDrive, user.HomeDrive, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypesAD.MiddleName) && !String.IsNullOrEmpty(user.MiddleName))
            {
                claims.Add(new Claim(ClaimTypesAD.MiddleName, user.MiddleName, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypesAD.SamAccountName) && !String.IsNullOrEmpty(user.SamAccountName))
            {
                claims.Add(new Claim(ClaimTypesAD.SamAccountName, user.SamAccountName, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypes.Surname) && !String.IsNullOrEmpty(user.Surname))
            {
                claims.Add(new Claim(ClaimTypes.Surname, user.Surname, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypesAD.UserPrincipalName) && !String.IsNullOrEmpty(user.UserPrincipalName))
            {
                claims.Add(new Claim(ClaimTypesAD.UserPrincipalName, user.UserPrincipalName, ClaimValueTypes.String));
            }
            if (claimTypes.Contains(ClaimTypesAD.VoicePhone) && !String.IsNullOrEmpty(user.VoiceTelephoneNumber))
            {
                claims.Add(new Claim(ClaimTypesAD.VoicePhone, user.VoiceTelephoneNumber, ClaimValueTypes.String));//WorkPhone? Format? e.g. https://en.wikipedia.org/wiki/E.123 or https://en.wikipedia.org/wiki/Microsoft_telephone_number_format
            }
            if (claimTypes.Contains(ClaimTypesAD.AccountExpiration) && user.AccountExpirationDate.HasValue)
            {
                claims.Add(new Claim(ClaimTypesAD.AccountExpiration, user.AccountExpirationDate.RoundTripString(), ClaimValueTypes.DateTime));//ClaimTypes.Expiration?
            }
            if (claimTypes.Contains(ClaimTypesAD.AccountLockout) && user.AccountLockoutTime.HasValue)
            {
                claims.Add(new Claim(ClaimTypesAD.AccountLockout, user.AccountLockoutTime.RoundTripString(), ClaimValueTypes.DateTime));
            }
            if (claimTypes.Contains(ClaimTypesAD.LastBadPassword) && user.LastBadPasswordAttempt.HasValue)
            {
                claims.Add(new Claim(ClaimTypesAD.LastBadPassword, user.LastBadPasswordAttempt.RoundTripString(), ClaimValueTypes.DateTime));
            }
            if (claimTypes.Contains(ClaimTypesAD.LastLogon) && user.LastLogon.HasValue)
            {
                claims.Add(new Claim(ClaimTypesAD.LastLogon, user.LastLogon.RoundTripString(), ClaimValueTypes.DateTime));
            }
            if (claimTypes.Contains(ClaimTypesAD.LastPasswordSet) && user.LastPasswordSet.HasValue)
            {
                claims.Add(new Claim(ClaimTypesAD.LastPasswordSet, user.LastPasswordSet.RoundTripString(), ClaimValueTypes.DateTime));
            }
            if (claimTypes.Contains(ClaimTypesAD.PermittedLogonTimes) && user.PermittedLogonTimes != null)
            {
                claims.Add(LogonTimes.PermittedLogonTimes(user.PermittedLogonTimes).ToClaim(serializationFormat));//TODO: series of claims instead of serialized?
            }
            return(claims);
        }