PWM 2.0.3 - 5015 ERROR_INTERNAL password.pwm.http.servlet.changepw.PrivateChangePasswordServlet:change

136 views
Skip to first unread message

Nathaniel Mitchell

unread,
Aug 11, 2022, 10:07:50 PM8/11/22
to pwm-general
Hi all,

Got an issue on a brand new installation of PWM (it's also my first installation of PWM, so I could have a config or 6 wrong). I am getting this error when doing a password change, the user account is a standard MS AD account with the password configured to change immediately. 

I've setup a post-password change action of GET a URL from a server (simple PHP script that acts as an API and executes thing, its not the best but it needs to last 6 months before this old system is killed). Its sole purpose is to allow the new password on the new AD domain to be "sync'd" to the old AD domain.

Notes
  • PWM runs on a dedicated VM with Ubuntu 20.04 LTS 64bit
    • Connected to a MS AD domain (2016 functionality)
  • The web service is a custom PHP script
    • Using Apache with a CA for HTTPS. Certificate is imported on the configuration screen
    • The PHP script doesnt have any authentication
      • Was using 3 parameters, username, password, and secret key
      • The secret key was URL encoded and put statically in the request
    • The request is done as a GET request with the information in the URL itself.
Below is the output from the logs.

2022-08-12T01:39:07Z, ERROR, http.PwmResponse, {YVIs4,MyTest} 5015 ERROR_INTERNAL (unexpected error during action handler for 'password.pwm.http.servlet.changepw.PrivateChangePasswordServlet:change', error: Illegal character in path at index 55: https://serverdc02.company.com/password/user/MyTest/]umpyBean76) [192.168.2.24]
2022-08-12T01:39:07Z, FATAL, servlet.AbstractPwmServlet, {YVIs4,MyTest} unexpected error: 5015 ERROR_INTERNAL (unexpected error during action handler for 'password.pwm.http.servlet.changepw.PrivateChangePasswordServlet:change', error: Illegal character in path at index 55: https://serverdc02.company.com/password/user/MyTest/]umpyBean76) [192.168.2.24]
2022-08-12T01:39:07Z, ERROR, servlet.AbstractPwmServlet, {YVIs4,MyTest} unexpected error during action handler for 'password.pwm.http.servlet.changepw.PrivateChangePasswordServlet:change', error: Illegal character in path at index 55: https://serverdc02.company.com/password/user/MyTest/*hidden* [192.168.2.24] (stacktrace follows)
java.lang.Throwable: Illegal character in path at index 55: https://serverdc02.company.com/password/user/MyTest/]umpyBean76
at java.base/java.net.URI.create(URI.java:883)
at password.pwm.svc.httpclient.PwmHttpClientRequest.isHttps(PwmHttpClientRequest.java:69)
at password.pwm.svc.httpclient.ApachePwmHttpClient.makeRequestImpl(ApachePwmHttpClient.java:363)
at password.pwm.svc.httpclient.ApachePwmHttpClient.makeRequest(ApachePwmHttpClient.java:345)
at password.pwm.util.operations.ActionExecutor.executeWebserviceAction(ActionExecutor.java:226)
at password.pwm.util.operations.ActionExecutor.executeAction(ActionExecutor.java:92)
at password.pwm.util.operations.ActionExecutor.executeActions(ActionExecutor.java:73)
at password.pwm.util.password.PasswordUtility.setActorPassword(PasswordUtility.java:367)
at password.pwm.http.servlet.changepw.ChangePasswordServletUtil.executeChangePassword(ChangePasswordServletUtil.java:220)
at password.pwm.http.servlet.changepw.ChangePasswordServlet.processChangeAction(ChangePasswordServlet.java:223)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at password.pwm.http.servlet.ControlledPwmServlet.dispatchMethod(ControlledPwmServlet.java:122)
at password.pwm.http.servlet.ControlledPwmServlet.processAction(ControlledPwmServlet.java:163)
at password.pwm.http.servlet.AbstractPwmServlet.handleRequest(AbstractPwmServlet.java:125)
at password.pwm.http.servlet.AbstractPwmServlet.doPost(AbstractPwmServlet.java:75)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153)
at password.pwm.http.filter.AuthenticationFilter.processAuthenticatedSession(AuthenticationFilter.java:211)
at password.pwm.http.filter.AuthenticationFilter.processFilter(AuthenticationFilter.java:108)
at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153)
at password.pwm.http.filter.SessionFilter.processFilter(SessionFilter.java:111)
at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153)
at password.pwm.http.filter.ApplicationModeFilter.processFilter(ApplicationModeFilter.java:82)
at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153)
at password.pwm.http.filter.ObsoleteUrlFilter.processFilter(ObsoleteUrlFilter.java:65)
at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at password.pwm.http.filter.RequestInitializationFilter.initializeServletRequest(RequestInitializationFilter.java:245)
at password.pwm.http.filter.RequestInitializationFilter.doFilter(RequestInitializationFilter.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.github.ziplet.filter.compression.CompressingFilter.doFilter(CompressingFilter.java:263)
at password.pwm.http.filter.GZIPFilter.doFilter(GZIPFilter.java:81)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at password.pwm.http.filter.CookieManagementFilter.doFilter(CookieManagementFilter.java:77)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.Throwable: Illegal character in path
at java.base/java.net.URI$Parser.fail(URI.java:2913)
at java.base/java.net.URI$Parser.checkChars(URI.java:3084)
at java.base/java.net.URI$Parser.parseHierarchical(URI.java:3166)
at java.base/java.net.URI$Parser.parse(URI.java:3114)
at java.base/java.net.URI.<init>(URI.java:600)
at java.base/java.net.URI.create(URI.java:881)
... 73 more

2022-08-12T01:39:07Z, INFO , password.PasswordUtility, {YVIs4,MyTest} password for user 'CN=Test user,OU=Staff,OU=Users,OU=COMPANY,DC=corp,DC=COMPANY,DC=com (default)' has been changed by CN=Service Account for PWM,OU=Users - Service Accounts,OU=COMPANY,DC=corp,DC=COMPANY,DC=com (21ms) [192.168.2.24]
2022-08-12T01:39:02Z, INFO , event.AuditService, {YVIs4} audit event: {"perpetratorID":"MyTest","perpetratorDN":"CN=Test user,OU=Staff,OU=Users,OU=COMPANY,DC=corp,DC=COMPANY,DC=com","perpetratorLdapProfile":"default","sourceAddress":"192.168.2.24","sourceHost":"192.168.2.24","type":"USER","eventCode":"AUTHENTICATE","guid":"0de6e159-28af-446a-8834-68476712b195","timestamp":"2022-08-12T01:39:02Z","message":"type=AUTH_BIND_INHIBIT, source=LOGIN_FORM","narrative":"MyTest (CN=Test user,OU=Staff,OU=Users,OU=COMPANY,DC=corp,DC=COMPANY,DC=com) has authenticated","xdasTaxonomy":"XDAS_AE_AUTHENTICATE_ACCOUNT","xdasOutcome":"XDAS_OUT_SUCCESS"} [192.168.2.24]

Nathaniel Mitchell

unread,
Aug 11, 2022, 11:06:36 PM8/11/22
to pwm-general
Forgot to note the configuration. I have tried without the basic auth, then set a random username & password (admin / admin).

Setting ⇨ Modules ⇨ Authenticated ⇨ Change Password ⇨ Profiles ⇨ default ⇨ Post Password Change Actions
Action name=OldDomain description=Submits username & password to the OLD domain to update the account there.
  WebServiceAction:
    method=get
    url=https://serverdc02.company.com/password/user/@User:ID@/@User:Password@
    headers={}
    username=admin
    password=admin
    successStatus=200

Jason Rivard

unread,
Aug 12, 2022, 1:16:15 AM8/12/22
to pwm-general
Bracket character is an illegal character in URL paths.  Put the values in the body, not the URL.

Nathaniel Mitchell

unread,
Aug 12, 2022, 1:38:11 AM8/12/22
to pwm-general
Hi Jason,

I need the values in the URL, the API doesnt process the body.

Jason Rivard

unread,
Aug 12, 2022, 5:36:56 AM8/12/22
to pwm-general
Prevent having URL-invalid invalid characters in your passwords?  Otherwise it's a little late to change HTTP protocol.

Paul Hodgdon

unread,
Aug 12, 2022, 6:54:28 AM8/12/22
to pwm-g...@googlegroups.com
Wrap your password in an encode macro.

--
You received this message because you are subscribed to the Google Groups "pwm-general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pwm-general...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pwm-general/9060b156-9023-44ad-ba5d-3d40a4c5d4fen%40googlegroups.com.
--

Paul Hodgdon
Principal Consultant | Identity Works LLC
Epping | New Hampshire 03042 | USA
+1 603 661 1508 (mobile) | +1 603 734 2681 (office)
www.identityworksllc.com

     

jason.e...@gmail.com

unread,
Aug 12, 2022, 9:49:46 AM8/12/22
to pwm-general
I would also recommend not using GET for that, it gets stored in server access logs, etc.. in plain text, especially for your domain. It is really easy to switch your PHP script to POST, just change your $_GET['your_param'] to $_POST['your_param'] and in PWM change to POST action and then set content type to application/x-www-form-urlencoded and in the body set your params like  username=@User:ID@&password=@User:Password@ . If you still want to use GET you could always put them into the header section and then adjust php script to pull from header

Nathaniel Mitchell

unread,
Aug 14, 2022, 9:02:33 PM8/14/22
to pwm-general
Hi @Paul - How would I do that?

Hi @Jason - Its looking like I am going to have to learn to code php or asp a bit more then. The getting it trapped in the logs isnt too much of an issue; as its all internal traffic and only 3 people have access (the domain admins) AND the fact the domain in question is literally on its last few months of being alive (yes, party time soon).

Jason Everling

unread,
Aug 15, 2022, 10:16:04 AM8/15/22
to pwm-general
For the encode macro, you will need to adjust PHP still but, replace @User:Password@ with I believe @Encode:User:Password@ , it has been forever since I used it before. I believe it is also URL encoded so in PHP you will need to adjust your parameters like if your are using $password = $_GET['password'] to something like  $password = urldecode( $_GET['password']) to get the decoded value

You received this message because you are subscribed to a topic in the Google Groups "pwm-general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pwm-general/hsvyuvr-XNA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pwm-general...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pwm-general/b477bea9-e6c3-404b-8bf8-a3f6459804f8n%40googlegroups.com.

Jason Everling

unread,
Aug 15, 2022, 10:19:25 AM8/15/22
to pwm-general
Ehh I fudged that I think,

it would be @Encode:base64:[[@User:Password@]]@ then in PHP use base64_decode( $_GET['password']))

Nathaniel Mitchell

unread,
Aug 15, 2022, 7:09:46 PM8/15/22
to pwm-general
Cheers for that. I literally saw that option yesterday; and now have managed to break my installation. Go me.

I am working on changing the script to receive a POST and see if i can keep it internally, instead of calling a powershell script to update the password on the remote domain.

Jason Everling

unread,
Aug 15, 2022, 7:55:22 PM8/15/22
to pwm-g...@googlegroups.com

I can send you a simple php script to update AD, give me a few minutes

Nathaniel Mitchell

unread,
Aug 15, 2022, 8:11:45 PM8/15/22
to pwm-general
This one is for all.

I'll do another post later with a github thing later. But this is the basis of the PHP script that accepts both input via a GET request and now via JSON on a POST request.

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

$MySecretKey = "ccc";

require './vendor/autoload.php';

$app = new \Slim\App;
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
    $name = $args['name'];
    $response->getBody()->write("Hello, $name");

    return $response;
});
$app->get('/user/{username}/{password}/{secretkey}', function (Request $request, Response $response, array $args) {
    $username = substr($args['username'],1);
    $password = substr($args['password'],1);
    $secretkey = $args['secretkey'];
    global $MySecretKey;

    if ($secretkey == $MySecretKey) {
        //$ExecuteCMD = 'powershell.exe -ExecutionPolicy ByPass "C:\scripts\test.ps1" ';
        //$ExecuteCMD .= "-username $username -NewPassword $password";
        //exec($ExecuteCMD, $ExecuteOutput, $ExecuteResult);
        //$response->getBody()->write($ExecuteResult);
        $response->getBody()->write("Hello, <b>$username</b><br />");
        $response->getBody()->write("Your password is <b>$password</b><br />");
    } else {
        $response->getBody()->write("bad key");
    }
    return $response;
});
$app->post('/user2/{secretkey}', function (Request $request, Response $response, array $args) {
    $json = file_get_contents('php://input');
    $secretkey = $args['secretkey'];
    global $MySecretKey;

    $NewDetails = json_decode($json);
    $username = $NewDetails->username;
    $password = $NewDetails->password;

    if ($secretkey == $MySecretKey) {
        //$ExecuteCMD = 'powershell.exe -ExecutionPolicy ByPass "C:\scripts\test.ps1" ';
        //$ExecuteCMD .= "-username $username -NewPassword $password";
        //exec($ExecuteCMD, $ExecuteOutput, $ExecuteResult);
        //$response->getBody()->write($ExecuteResult);
        $response->getBody()->write("Hello, <b>$username</b><br />");
        $response->getBody()->write("Your password is <b>$password</b><br />");
    } else {
        $response->getBody()->write("bad key");
    }
    return $response;
});
$app->run();

Nathaniel Mitchell

unread,
Aug 16, 2022, 3:33:13 AM8/16/22
to pwm-general
Here is one I wrote today.... after much googling. Its a basic script, assumes everything is 100% and trusts all inputs.

Jason Everling

unread,
Aug 16, 2022, 10:17:54 AM8/16/22
to pwm-g...@googlegroups.com

Meant to send last night and from quick search from a PWM post I did years ago, I created a single php file to update AD password but I cannot find it when searching forum and wish I now just made it into gist instead of pastebin :/

 

Although its beyond PWM, from a quick glance, your having to use PowerShell still because AD cannot take straight text to unicodePwd, use below,

 

$unicodePwd = iconv('UTF-8', 'UTF-16LE', '"' . $MyNewPassword . '"');

$EncPassword["unicodePwd"] = $unicodePwd;

 

You can simplify all of this and make so much more human readable and without using 3rd party libraries I can send a request to your GitHub, just let me know.

Nathaniel Mitchell

unread,
Aug 16, 2022, 7:35:23 PM8/16/22
to pwm-general
Is all good, your new line is a lot cleaner than the way I found online to do. I'll update the repo.

Yeah powershell was being used, because I was being lazy at learning/finding examples for PHP.

Cheers for you assistance as well :) 

Reply all
Reply to author
Forward
0 new messages