Custom workflow - email user random generated password

 Hello guys,

 

I have just recently installed One Identity Password Manager version 5.7.0.1525 in our test-environment. We see that the existing workflows can not apply to our situation, and need to create a new simple custom workflow. We are looking for a self-selvice portal for our users where they simply can reset their password.

 

The workflow should consist of a user searching after his AD-user and then choose the custom workflow "Password email reset" workflow, a random generated password is set on the user account in AD (in addition: "user must change password at next logon" is checked), and an email is sent to the user with the password.

 

The best would be to email the user a link which he then access and set a new password - like the way facebook, gmail, etc do it. Is this possible? :)

 

Best regards

Bilal

  • Hello Bilal,

    There are a few problems which I see with this request, from a security standpoint.

    First, emailing a password is not a secure method. The services which allow you to reset your own password, like Facebook and Google, always send a link to a secure portal. The URL which is sent contains a single-use, time-sensitive token which allows you to authenticate for the purposes of resetting your password. This is generally accepted as a secure method.

    Second, how is the User going to access their email account, if their Active Directory account is locked out and it uses the same password?

    Password Manager has the access to reset the User's password directly. Once the User is registered, they can trigger that operation themselves. This is much simpler to implement than a secure portal which tracks single-use tokens, which also would have to tie into an external email system.

    Terrance C

    Social Media and Community Professional
    #iWork4OneIdentity

  • In reply to Terrance.Crombie:

    Hi Terrance,

    Thanks for your reply. Just to clarify our environment design, we want to implement Dell Password manager in our test environment which is seperate domain from the production. When a user reset his password an email would be sent to his account in the production domain. There is no AD trust between the domains. A user has to have acccess to production, before he can access the test environment.

    So the need is how we can create this custom workflow in Powershell with either, the first option as suggested in the main post. Or as you are mentioning the secure single-use, time-sensitive token. How can we implement this in our environment? Any examples would help us a lot.

    Kind regards
    Bilal
  • In reply to Bilal:

    Using a token for authentication would involve implementing a secure portal, as well as an API to tie into it. This is beyond the scope of the Password Manager solution, and I do not have any sample code which may help.

    We strongly recommend not emailing a password, so I don't have sample code for that, either. But an alternate solution which may meet your needs is to email a PIN.

    1) The User logs into the Password Manager portal, finds their Active Directory account, and triggers a Workflow.
    2) The Workflow would retrieve the User's Production email address which is stored in an attribute on the linked account in the test environment.
    3) The Workflow sends an email to this User's Production email address. The email contains a PIN, which the User would retrieve and enter into the Password Manager portal.
    4) The User resets their password.

    This would be similar to the passcode samples which are included with the Password Manager installation media in the SDK.

    Terrance C

    Social Media and Community Professional
    #iWork4OneIdentity

  • In reply to Terrance.Crombie:

    Hi,

    Thanks again for the suggestion, I was not aware of the samples. I like your suggestion and I have just tried to implement the SetPasscode example to test it. However having some difficulties.

    I created a new workflow with the name "Set Passcode" containing one custom acitivity "Passcode" where I pasted in the powershell-script which was provided in the SetPasscode.txt, I uncommented the lines beginning with $EMAIL_SUBJECT and $EMAIL_BODY. In the "User Interface Designer" I did not do anything and on the "Activity name" I just prode "Passcode"


    When I then access the PMUser interfae and search for a specific user and then get logged in as the user I choose the "Set Passcode" workflow and receive the following error:

    *Domain not specified


    ---
    Do I need to specify domain anywhere? Since it manages to retrieve the AD user and therefor also should be able to retrieve the domain.

    Please let me know if I am doing anything wrong, that would be really helpful.

    Kind regards
    Bilal
  • In reply to Bilal:

    I don't believe that implementation is a useful sample for this design.

    From the readme.txt:

    This sample demonstrates a custom web service that assigns passcodes to users.

    The web service allows interacting with external systems so that they can trigger passcode assignment and know the passcode that was assigned.

    To use this sample:

    1. Create a custom web service with the script provided in the "SetPasscode.txt" file.

    2. Form and open the following URL:
    http://<pmserver>/PMUser/ws/<service_URL>?user=<user_sAMAccountName>&domain=<domain_FQDN>
    Where:
    - pmserver - name of the computer on which the Password Manager Service is installed.
    - service_URL - URL specified when creating the custom web service.
    - user_sAMAccountName - sAMAccountName of a user to whom a passcode is assigned.
    - domain_FQDN - fully qualified domain name of a domain to which the user belongs. Note: a connection to this domain must be configured in Password Manager.

    3. Expected result is an XML document that contains the passcode and passcode creation log.



    You'd want to take snippets from it instead of the entire implementation.

    For example, this is relevant:

    #Obtain user's GUID
    $userId = $user.objectGUID

    #Generate a passcode for a user
    $PASSCODE= $global.GeneratePasscode($PASSCODE_LENGTH)
    $log += "Generated passcode $PASSCODE"

    #Assign passcode to a user
    $global.QAProfileAssignPasscode($connection, $userId, $passcode, $PASSCODE_LIFETIME)
    $log += "Passcode assigned to user $userName"

    if ($EMAIL_SUBJECT -ne "" -and $EMAIL_BODY -ne "")
    {
    #Send e-mail with passcode, if user has an e-mail address
    if ($user.mail -ne "")
    {
    $log +="Sending passcode to $($user.mail)"
    $subject = $ExecutionContext.InvokeCommand.ExpandString($EMAIL_SUBJECT)
    $body = $ExecutionContext.InvokeCommand.ExpandString($EMAIL_BODY)
    $global.EmailUserHtml($mail, $subject, $body)
    }
    else
    {
    $log +="User account has no mail, will not send e-mail with passcode"
    }
    }

    Terrance C

    Social Media and Community Professional
    #iWork4OneIdentity

  • I agree, it is an interesting 2FA scenario: when two independent credentials and mail systems are used to 2FA each other (AD01\EX01 - AD02\EX02).
    - AD01\jsmith resets password via http://AD01/PMUser on AD01\jsmith - email send to jmith@ad02.com with AD01\jsmith new password (clear text)
    Assumption: AD01 and AD02 must be in Sync. AD01\jsmith ad account must be resolved/mapped programatically to AD02\jsmith email address (example (a) AD01\jsmith.CA10 = jsmith@ad02.com, (b) PWM ADmin Service to make ldap query against AD02\DC with AD01\jsmith EmployeeID or sAMAccountName = "jsmith")

    Aidar Karabalaev

  • In reply to Terrance.Crombie:

    Thanks a lot for helping me here.

    I misunderstood the sample code, and now I tried your code. The workflow went through withotut any errors however I am not receiving the passcode on my mail. I have tested the SMTP test settings in the PMadmin interface, and received a test mail. But I am not recieving the mail after finishing the workflow. I have verified that my AD-user is configured with the correct e-mail address - which is the same I tested t he mail settings with.

    Am I right that $user.mail retrieved the value from the selected users AD email attribute?

    Also tried to check the logs, but did not see anything related.

    Kind regards
    Bilal
  • In reply to Bilal:

    I haven't tried this particular snippet in my lab.

    I would expect that the $user.mail variable would contain the email address from the Test Domain, in your context. To confirm, try to write this to a file, using something similar to:

    $user.mail | out-file c:\temp\scriptLogging.txt -append

    Insert this before the email is sent, and ensure that you have a c:\temp directory on the Password Manager host.

    Terrance C

    Social Media and Community Professional
    #iWork4OneIdentity

  • In reply to Terrance.Crombie:

    Thanks for that. I belive the reason for the code snippet not working is because several parameters are not defined.

    Just modified the the code you pasted, for example are following variables not defined: 

    $connection (in the SetPasscode it was defined by $global.GetDirectoryConnectionByName($domain) )


    I belive the best is if you could test the code in your test environment to see what is the for it failing.

    That would be really helpful, I am new to Dell Identity Password Manager and this is really painful trying to solve.

    I really appriciate your effort to help me here. As you suggested the custom workflow which will solve my problem is:

    * A passcode is set on the "logged on user" and sent to the users email (defined in the AD attribute). Can this be easily solved?

     

    Kind regards

    Bilal

  • In reply to Bilal:

    In the sample, the script was tying into a custom web service which accepted a Domain FQDN. This is for the purposes of extensibility. In your use case, your Users will always be in the same Domain, so you don't need to capture this. Just hard-code it, and then use the documented methods.

    I'm sorry, but implementing this in my lab and presenting you with a completed solution is outside of the scope of my support. If you require assistance with implementing a custom solution, I suggest that you engage our Professional Services Team.

    You can also post your code here and seek feedback.

    Terrance C

    Social Media and Community Professional
    #iWork4OneIdentity

  • In reply to Terrance.Crombie:

    Thank you for help. However, I have tried to hard-core both the $domain and $user as its defined in the
    $user = $global.GetUserByName($connection, $userName, [string[]]("objectGUID", "mail"))

    However, I have been triying to find out what the in-process variables is for the "logged in user". As for instance, domain, user name, mail, etc. I am just trying to make this code work so I have a proof-of-concept with Dell one password manager. :)

    I would like to appriciate your help until now.

    Here is my code until now:

     ---

    #Passcode length

    $PASSCODE_LENGTH = 12

     

    #Passcode lifetime in minutes

    $PASSCODE_LIFETIME = 1440 #(1 day)

     

    #Uncomment these lines to send e-mail to a user, if he has e-mail address

    #Variable $PASSCODE will contain user's passcode, all other variables are available too

    $EMAIL_SUBJECT = 'Passcode'

    $EMAIL_BODY = 'Your passcode is $PASSCODE'

     $domain='my.domain.com'

    #Obtain Password Manager connection to the specified domain
    $connection = $global.GetDirectoryConnectionByName($domain)

    #If there is none, throw an exception
    if ("$connection" -eq "") {
    throw "Connection to domain $domain not found in Password Manager!"
    }

     

    #Obtain user's GUID

    $userId = $user.objectGUID

     

    #Generate a passcode for a user

    $PASSCODE= $global.GeneratePasscode($PASSCODE_LENGTH)

     

    #Assign passcode to a user

    $global.QAProfileAssignPasscode($connection, $userId, $passcode, $PASSCODE_LIFETIME)

     

    if ($EMAIL_SUBJECT -ne "" -and $EMAIL_BODY -ne "")

    {

    #Send e-mail with passcode, if user has an e-mail address

    if ($user.mail -ne "")

    {

    $subject = $ExecutionContext.InvokeCommand.ExpandString($EMAIL_SUBJECT)

    $body = $ExecutionContext.InvokeCommand.ExpandString($EMAIL_BODY)

    $global.EmailUserHtml($mail, $subject, $body)

    }

    else

    {

    $log +="User account has no mail, will not send e-mail with passcode"

    }

    }

    ---
    Kind regards
    Bilal

  • In reply to Bilal:

    This script sample should be useful:


    function PostExecuting($workflow, $activity)
    {
    if ($activity.State.IsSuccess)
    {

    #gets the User from the Workflow context
    $PMUser = $workflow.Userinfo

    $PMUser | out-file c:\temp\scriptLogging.txt -append

    #gets the GUID of the User
    $UserGUID = $PMUser.id

    $UserGUID | out-file c:\temp\scriptLogging.txt -append

    }
    else
    {

    }
    }

    Terrance C

    Social Media and Community Professional
    #iWork4OneIdentity

  • In reply to Terrance.Crombie:

    Hi Terrence,

    Thanks a lot for your time and help. I have managed to do a lot after your last post. I managed to retrieve the user information and domain. The passcode is being generated and sent to the email and logging is working. I have been debugging a lot to make it work.

    The only thing that is still not working is that the generated passcode is not assigned to the user-account. The following line does not seem to work:

    $global.QAProfileAssignPasscode($connection, $userId, $PASSCODE, $PASSCODE_LIFETIME)
    # Log to see if the passcode is set on the user
    "After the passcode is set:" | out-file d:\temp\scriptLogging.txt -append
    $PMUser | out-file d:\temp\scriptLogging.txt -append

    I also log to see if the passcode is set on the user, as you can see above. The result is:

    HasPasscode : False

    So my conclusion so far is that the "$global.QAProfileAssignPasscode" does not set the passcode on the user.

    What could be the reason for the passcode not being set? The passcode is being generated and sent to the users mail, and I have managed it to print out in the log. So that is not the issue.

    Kind regards
    Bilal
  • In reply to Bilal:

    This sounds like great progress.

    Without seeing your code, i would try to output the values of following at runtime to a file to see what they contain:

    $global
    $connection
    $userId
    $PASSCODE
    $PASSCODE_LIFETIME

    Terrance C

    Social Media and Community Professional
    #iWork4OneIdentity

  • In reply to Terrance.Crombie:

    Yeah, that what I did.

    Everything gets printed out and looks correct, without "@global"
    The result is: QPM.Service.PowerShell.Global

    Which does not look right?

    Kind regards
    Bilal