Skip to content
This repository has been archived by the owner on Jun 2, 2023. It is now read-only.

Feature Request - Deal with "User must change password" #21

Closed
bernhardschmidt opened this issue May 6, 2016 · 35 comments
Closed

Feature Request - Deal with "User must change password" #21

bernhardschmidt opened this issue May 6, 2016 · 35 comments

Comments

@bernhardschmidt
Copy link

As already requested in #19 (and #15) it would be great if passcore could be used to deal with users that have to change their password at the next logon.

@bernhardschmidt bernhardschmidt changed the title Feature Request: Deal with "User must change password" Feature Request - Deal with "User must change password" May 6, 2016
@adalfa
Copy link

adalfa commented Aug 12, 2016

Hi, I've worked out a patch to make it work by managing the Lastpasswordset attribute; with some security work at Active directory level (granting a user reset and change password permission e read/write pwdlastset attribute) i was able to make it work on 2012 R2 domain.
This is the first time on GitHub and i do not kown how contribute, I attach the PasswordController.cs source file
PasswordController.cs.txt

@larvel
Copy link

larvel commented Aug 15, 2016

@adalfa Can you explain in detail how you managed to get this working?

@AnthonyKolka
Copy link

@larvel I would assume that you would replace the PasswordController.cs file with the one they attached as a .txt file, just rename it after downloading. Of course those changes should be thoroughly tested before putting in production to ensure that they do not cause unforeseen security issues.

@larvel
Copy link

larvel commented Aug 15, 2016

@savaticus, we already tried that. When the user has must change password at change logon we cannot get the user to change his own password. We have tried all sorts of permission stuff.

@adalfa
Copy link

adalfa commented Aug 15, 2016

@larvel
After the code change, i've changed the identity of the application pool with a user that has the following right at the AD level:
1)reset/change user password
2)read/write on pwdlastset attribute

the code attached adds some logging on the failure to write the pwdlastset attribute, can you please verify?
@savaticus: i do not tested thoroughly the change; surely I left the pwdlastset setted to -1 even if the user authentication failed

@larvel
Copy link

larvel commented Aug 16, 2016

@adalfa the Application pool has been configured to run as a domain admin account.

The error is:
Error: The system cannot contact a domain controller to service the authentication request. Please try again later. (Exception from HRESULT: 0x800704F1)

The AppSettings are as follows:
"AppSettings": {
"RecaptchaPrivateKey": "",
"PasswordChangeOptions": {
"UseAutomaticContext": true,
"LdapHostname": "pdc.domain.local", (We even tried with IP)
"LdapPort": 389,
"LdapUsername": "administrator",
"LdapPassword": "PassWord"

@jkberry
Copy link

jkberry commented Aug 16, 2016

@adalfa Thank you for this patch. Can you confirm that the change to the pwdLastSet attribute from null to -1 is only done once PassCore has successfully authenticated the user using the current password? Your code appears to come before the original section commented "Validate user credentials." It also does not appear that the patch resets the value from -1 to null in the event of a failed SetPassword or ChangePassword attempt.

@adalfa
Copy link

adalfa commented Aug 17, 2016

@jkberry I had to modify the order of the change of the attribute when I've moved to a different domain functional level (from 2003 to 2012 R2)

@jkberry
Copy link

jkberry commented Aug 17, 2016

@adalfa Did you discover that the pwdLastSet attribute change must occur before the credential verification when using the Windows Server 2012 R2 functional level?

@adalfa
Copy link

adalfa commented Aug 17, 2016

Yes, on an 2003 domain I had no problem at all; on the 2012 R2 I had an error.
It reminded me of some discussions on stackoverflow (I do not have the link) and it make sense to me to fail the validation since the user must change password

@jkberry
Copy link

jkberry commented Aug 17, 2016

@adalfa Thanks for the additional information. Do you recall how you set the service account permissions for the application pool user? I expect that this could be done through the GUI but I'd like to see if it can be done programmatically through PowerShell.

@AnthonyKolka
Copy link

You guys know that running an IIS application as an admin and especially a domain admin is a bad idea right? If you have any other sites on tat server and one of them gets compromised it is then possible for an attacker to retrieve the credentials for the other site.

@adalfa
Copy link

adalfa commented Aug 17, 2016

Is the reason why I've delegated such rights to a special user

@jkberry
Copy link

jkberry commented Aug 17, 2016

@savaticus, @adalfa was not suggesting that the application should be configured to run as an administrator. A service account with the ability to change the value of the pwdLastSet attribute should present very limited risk and is far less permission that many similar tools require.

@jkberry
Copy link

jkberry commented Aug 17, 2016

@adalfa do you think that it would be possible for the password change to be initiated by the actual user using the provided credentials as opposed to the service account user associated with the application pool?

@adalfa
Copy link

adalfa commented Aug 17, 2016

@jkberry Maybe for the users that have no "password reset at next logon", but i think that the other would not have the right to logon

@jkberry
Copy link

jkberry commented Aug 18, 2016

@adalfa I see how the principalContext.ValidateCredentials method would fail if pwdLastSet is null for the user.

Could you update your patch to reset pwdLastSet to null if either principalContext.ValidateCredentials or the password change fails? Without resetting the value, it appears that anyone could enter the username in PassCore with an invalid password and permanently remove the requirement for a password change for that user.

Also, is the password change requirement true when pwdLastSet is null, 0, or either?

https://msdn.microsoft.com/en-us/library/aa746510(v=vs.85).aspx

@jkberry
Copy link

jkberry commented Aug 19, 2016

Below is a PowerShell script to assign the appropriate permissions to the service account user when using the patch provided by @adalfa. Much of this code was derived from this post by Joe Corey.

Import-Module ActiveDirectory
cd ad:

$user = "username"
$path = "OU=orgunit,DC=domain,DC=suffix"
$userSchemaGUID = "bf967aba-0de6-11d0-a285-00aa003049e2"
$pwdLastSetGUID = "bf967a0a-0de6-11d0-a285-00aa003049e2"
$resetPasswordGUID = "00299570-246d-11d0-a768-00aa006e0529"

$userSID = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser $user).SID

$acl = Get-ACL -Path ($path)

$acl.AddAccessRule((New-Object System.DirectoryServices.PropertyAccessRule $userSID, "Allow", "Read", $pwdLastSetGUID, "All", $userSchemaGUID))
$acl.AddAccessRule((New-Object System.DirectoryServices.PropertyAccessRule $userSID, "Allow", "Write", $pwdLastSetGUID, "All", $userSchemaGUID))
$acl.AddAccessRule((New-Object System.DirectoryServices.ExtendedRightAccessRule $userSID, "Allow", $resetPasswordGUID, "All", $userSchemaGUID))

Set-ACL -ACLObject $acl -Path ("AD:\"+($path))

@jkberry
Copy link

jkberry commented Aug 21, 2016

Update: it appears that you do not have to change the user associated with the application pool in IIS. I am able to reset passwords for users who are required to change their password at next logon by using the following modifications:

  1. Replace the default PasswordController.cs with @adalfa's patch
  2. Create a standard Active Directory user to use as the service account
  3. Use the PowerShell script above to provide the service account with appropriate permissions
  4. Modify the PasswordChangeOptions section in appsettings.json to set UseAutomaticContext to false and enter explicit Active Directory hostname and port information and supply the service account username and password

@adalfa
Copy link

adalfa commented Aug 23, 2016

@jkberry I've finally managed to preserve the "must change password at next logon" flag
PasswordController.cs.txt

@jkberry
Copy link

jkberry commented Aug 23, 2016

Thanks @adalfa!

@eureekasigns
Copy link

@adalfa - thanks for the great workaround on this!!!
Replaced / renamed file with yours, and restarted the site / application pool. Works great :)

Only thing I'd add is:
@jkberry - step 5 - recycle application pool (and the site, for good measure)

@smegnl
Copy link

smegnl commented Oct 14, 2016

NICE! Thanks! I just did two steps..

  1. replaced the file
  2. restarted the pool / iis

@roaima
Copy link

roaima commented Dec 1, 2016

@jkberry your Powershell is very nice, thank you. However, it seems to grant too much privilege.

The "Reset password" privilege allows a user to specify a new password without regard to any password history. So it becomes possible for a user with password "Hello123" to reset it to "Hello123". Since the code (correctly) resets the password expiry information this provides a means for a user to keep the same password forever.

The "Change password" privilege honours the password history, but the new code does not recognise the return values properly from the act of changing the password. A successful password change presents no success message and the initial change password remains visible, leading users to assume their password change has not occurred. Specifying an invalid password (such as the same one again) triggers the error « There was an error changing your password // Error Information: Exception has been thrown by the target of an invocation. »

@smegnl
Copy link

smegnl commented Dec 1, 2016 via email

@adalfa
Copy link

adalfa commented Dec 3, 2016

@roaima @smegnl : I remind that i had to change the history policy on AD in order to test with the same password in early tests; i do not verify extensively. The problem occurs after the last patch in order to preserve "must change password at next logon"?
thx

@mariodivece
Copy link
Member

This is a year old and outside of the scope of PassCore. Closing.

@veinom
Copy link

veinom commented Jan 8, 2018

I'm trying to implement this fix but I can't figure out where to put the new PasswordController.cs - I see that it is located in the Controllers folder of the source, but if I'm supposed to put it there and then recompile (I previously downloaded the 3.0 binary), I'm getting error messages about PasswordController.cs when running the dotnet publish ... any help?

Thanks.

@geoperez
Copy link
Member

geoperez commented Jan 8, 2018

What error message are you getting?

@veinom
Copy link

veinom commented Jan 8, 2018

Here's an example (multiple versions of the error below show up) - It's been forever since I've compiled code, so it's likely I'm just not doing it right ... I took the source code, deleted the old .cs file and put in the new .cs file, then tried dotnet publish --framework net461 --output "c:\webapps\PassCore" --configuration Release

Restore completed in 98.48 ms for C:\webapps\src\src\Unosquare.PassCore.Web\Unosquare.PassCore.Web.csproj.
Restore completed in 57.02 ms for C:\webapps\src\src\Unosquare.PassCore.Web\Unosquare.PassCore.Web.csproj.
Controllers\PasswordController.cs(3,21): error CS0234: The type or namespace name 'AspNet' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [C:\webapps\src\src\Unosquare.PassCore.Web\Unosquare.PassCore.Web.csproj]

@geoperez
Copy link
Member

geoperez commented Jan 8, 2018

We changed from ASP.NET Core 1 to 2. You may need to upgrade some namespaces and classes.

@veinom
Copy link

veinom commented Jan 8, 2018

You're right, that was the issue - the previously patched code was for an old version, so the code won't work/compile with the current version out there. I'm working with the updated PasswordController.cs to see if I can apply the fix to it, will post if I'm successful.

@veinom
Copy link

veinom commented Jan 17, 2018

Just a note that it would be nice if this were officially supported. For new users we set the "must change password at next logon" flag so they have to make their own password instead of the default. Instead of making them logon to a PC to change it we'd like them to be able to update their AD password (and therefore their G Suite password via GAPS) via this page on a Chromebook. I can foresee this being a common occurrence elsewhere as time goes on.

I've edited the PasswordController.cs for Core 2 to have the code previously posted and it seems to work. I've attached it for others to look at it, but I haven't thoroughly debugged it so I can't say whether it's perfect or not. Use at your own risk.
PasswordController.cs.txt

Thanks for considering.

@collinks2
Copy link

Hello,
Am new to Github. Am not a developer.i am researching on how can i design a webpage for AD users to able to change and reset password with ease.Google directed me to passcore.what do i download to get stated? In the webpage sample ,i do not see the option of password reset in case the user forgets his password. I will appreciate any help

@dragonwarrior00
Copy link

On the new PasswordController.cs file I downloaded it and tried to compile but it produces an error. I have no issue compiling with the original PasswordController.cs file.

error CS0246: The type or namespace name 'AppSettings' could not be found (are you missing a using directive or an assembly referenc?) [C:\passcore-master\src\Unosquare.PassCore.Web\Unosquare.PassCore.web.scproj]

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests