예제 #1
0
파일: Sam.cs 프로젝트: 40a/PowerShell
        /// <summary>
        /// Set selected properties of a user.
        /// </summary>
        /// <param name="userHandle">Handle to an open SAM user.</param>
        /// <param name="sourceUser">
        /// A <see cref="LocalUser"/> object containing the data to set into the user.
        /// </param>
        /// <param name="setFlags">
        /// A combination of <see cref="UserProperties"/> values indicating the properties to be set.
        /// </param>
        /// <param name="password">A <see cref="System.Security.SecureString"/>
        /// object containing the new password.
        /// </param>
        /// <param name="passwordExpired">One of the
        /// <see cref="PasswordExpiredState"/> enumeration values indicating
        /// whether the password-expired state is to be explicitly set or
        /// left as is. If the <paramref name="password"/> parameter is null,
        /// this parameter is ignored.
        /// </param>
        /// <param name="setPasswordNeverExpires">
        /// Nullable value the specifies whether the PasswordNeverExpires bit should be flipped
        /// </param>
        private void SetUserData(IntPtr userHandle,
                                 LocalUser sourceUser,
                                 UserProperties setFlags,
                                 System.Security.SecureString password,
                                 PasswordExpiredState passwordExpired,
                                 bool? setPasswordNeverExpires)
        {
            IntPtr buffer = IntPtr.Zero;

            try
            {
                UInt32 which = 0;
                UInt32 status = 0;
                UInt32 uac = GetUserAccountControl(userHandle);
                USER_ALL_INFORMATION info = new USER_ALL_INFORMATION();

                if (setFlags.HasFlag(UserProperties.AccountExpires))
                {
                    which |= SamApi.USER_ALL_ACCOUNTEXPIRES;
                    info.AccountExpires.QuadPart = sourceUser.AccountExpires.HasValue
                                                 ? sourceUser.AccountExpires.Value.ToFileTime()
                                                 : 0L;
                }
                if (setFlags.HasFlag(UserProperties.Description))
                {
                    which |= SamApi.USER_ALL_ADMINCOMMENT;
                    info.AdminComment = new UNICODE_STRING(sourceUser.Description);
                }
                if (setFlags.HasFlag(UserProperties.Enabled))
                {
                    which |= SamApi.USER_ALL_USERACCOUNTCONTROL;
                    if (sourceUser.Enabled)
                        uac &= ~SamApi.USER_ACCOUNT_DISABLED;
                    else
                        uac |= SamApi.USER_ACCOUNT_DISABLED;
                }
                if (setFlags.HasFlag(UserProperties.FullName))
                {
                    which |= SamApi.USER_ALL_FULLNAME;
                    info.FullName = new UNICODE_STRING(sourceUser.FullName);
                }

                if (setFlags.HasFlag(UserProperties.PasswordNeverExpires))
                {
                    // Only modify the bit if a change was requested
                    if (setPasswordNeverExpires.HasValue)
                    {
                        which |= SamApi.USER_ALL_USERACCOUNTCONTROL;
                        if (setPasswordNeverExpires.Value)
                            uac |= SamApi.USER_DONT_EXPIRE_PASSWORD;
                        else
                            uac &= ~SamApi.USER_DONT_EXPIRE_PASSWORD;
                    }
                }

                if (setFlags.HasFlag(UserProperties.PasswordRequired))
                {
                    which |= SamApi.USER_ALL_USERACCOUNTCONTROL;
                    if (sourceUser.PasswordRequired)
                        uac &= ~SamApi.USER_PASSWORD_NOT_REQUIRED;
                    else
                        uac |= SamApi.USER_PASSWORD_NOT_REQUIRED;
                }

                if (which != 0)
                {
                    info.WhichFields = which;
                    if ((which & SamApi.USER_ALL_USERACCOUNTCONTROL) != 0)
                        info.UserAccountControl = uac;

                    buffer = Marshal.AllocHGlobal(ClrFacade.SizeOf<USER_ALL_INFORMATION>());
                    ClrFacade.StructureToPtr<USER_ALL_INFORMATION>(info, buffer, false);

                    status = SamApi.SamSetInformationUser(userHandle,
                                                          USER_INFORMATION_CLASS.UserAllInformation,
                                                          buffer);
                    ThrowOnFailure(status);
                    status = SamApi.SamFreeMemory(buffer);
                    buffer = IntPtr.Zero;
                }

                if (setFlags.HasFlag(UserProperties.UserMayChangePassword))
                    SetUserMayChangePassword(userHandle, sourceUser.SID, sourceUser.UserMayChangePassword);

                if (password != null)
                    SetUserPassword(userHandle, password, passwordExpired);
            }
            finally
            {
                if (buffer != IntPtr.Zero)
                {
                    ClrFacade.DestroyStructure<USER_ALL_INFORMATION>(buffer);
                    Marshal.FreeHGlobal(buffer);
                }
            }
        }
예제 #2
0
파일: Sam.cs 프로젝트: 40a/PowerShell
        /// <summary>
        /// Set a user's password.
        /// </summary>
        /// <param name="userHandle">Handle to an open User.</param>
        /// <param name="password">A <see cref="System.Security.SecureString"/>
        /// object containing the new password.
        /// </param>
        /// <param name="passwordExpired">One of the
        /// <see cref="PasswordExpiredState"/> enumeration values indicating
        /// whether the password-expired state is to be explicitly set or
        /// left as is.
        /// </param>
        private void SetUserPassword(IntPtr userHandle,
                                     System.Security.SecureString password,
                                     PasswordExpiredState passwordExpired)
        {
            if (password != null)
            {
                USER_SET_PASSWORD_INFORMATION info = new USER_SET_PASSWORD_INFORMATION();
                IntPtr buffer = IntPtr.Zero;

                try
                {
                    bool setPwExpire = false;

                    switch (passwordExpired)
                    {
                        case PasswordExpiredState.Expired:
                            setPwExpire = true;
                            break;

                        case PasswordExpiredState.NotExpired:
                            setPwExpire = false;
                            break;

                        case PasswordExpiredState.Unchanged:
                            setPwExpire = IsPasswordExpired(userHandle);
                            break;
                    }

                    info.Password = new UNICODE_STRING(password.AsString());
                    info.PasswordExpired = setPwExpire;

                    buffer = Marshal.AllocHGlobal(Marshal.SizeOf(info));
                    ClrFacade.StructureToPtr<USER_SET_PASSWORD_INFORMATION>(info, buffer, false);

                    var status = SamApi.SamSetInformationUser(userHandle,
                                                              USER_INFORMATION_CLASS.UserSetPasswordInformation,
                                                              buffer);
                    ThrowOnFailure(status);
                }
                finally
                {
                    if (buffer != IntPtr.Zero)
                    {
                        ClrFacade.DestroyStructure<USER_SET_PASSWORD_INFORMATION>(buffer);
                        Marshal.FreeHGlobal(buffer);
                    }
                }
            }
        }
예제 #3
0
파일: Sam.cs 프로젝트: 40a/PowerShell
        /// <summary>
        /// Update a local user with new properties.
        /// </summary>
        /// <param name="user">
        /// A <see cref="LocalUser"/> object representing the user to be updated.
        /// </param>
        /// <param name="changed">
        /// A LocalUser object containing the desired changes.
        /// </param>
        /// <param name="password">A <see cref="System.Security.SecureString"/>
        /// object containing the new password. A null value in this parameter
        /// indicates that the password is not to be changed.
        /// </param>
        /// <param name="passwordExpired">One of the
        /// <see cref="PasswordExpiredState"/> enumeration values indicating
        /// whether the password-expired state is to be explicitly set or
        /// left as is.
        /// If the <paramref name="password"/> parameter is null, this parameter
        /// is ignored.
        /// </param>
        /// <param name="setPasswordNeverExpires">
        /// Indicates whether the PasswordNeverExpires parameter was specified.
        /// </param>
        private void UpdateUser(LocalUser user,
                                LocalUser changed,
                                System.Security.SecureString password,
                                PasswordExpiredState passwordExpired,
                                bool? setPasswordNeverExpires)
        {
            UserProperties properties = UserProperties.None;

            if (user.AccountExpires != changed.AccountExpires)
                properties |= UserProperties.AccountExpires;

            if (user.Description != changed.Description)
                properties |= UserProperties.Description;

            if (user.FullName != changed.FullName)
                properties |= UserProperties.FullName;

            if (setPasswordNeverExpires.HasValue)
                properties |= UserProperties.PasswordNeverExpires;

            if (user.UserMayChangePassword != changed.UserMayChangePassword)
                properties |= UserProperties.UserMayChangePassword;

            if (user.PasswordRequired != changed.PasswordRequired)
                properties |= UserProperties.PasswordRequired;

            if (   properties != UserProperties.None
                || passwordExpired != PasswordExpiredState.Unchanged
                || password != null)
            {
                IntPtr userHandle = IntPtr.Zero;
                UInt32 status = 0;

                try
                {
                    status = SamApi.SamOpenUser(localDomainHandle,
                                                Win32.MAXIMUM_ALLOWED,
                                                user.SID.GetRid(),
                                                out userHandle);
                    ThrowOnFailure(status);

                    SetUserData(userHandle, changed, properties, password, passwordExpired, setPasswordNeverExpires);
                }
                finally
                {
                    if (userHandle != IntPtr.Zero)
                        status = SamApi.SamCloseHandle(userHandle);
                }
            }
        }