Thursday, December 26, 2019

Sailpoint Identity IQ QuickLink WorkFlow Default Input

All the WorkFlow which are getting invoked from the Quicklink has below default input parameters.














currentUserName - Current User
launcher - Lanucher of this quicklink
quicklink - Name of the QuickLink
quickLinkIdentityId - Identity involved in this quicklink
quickLinkIdentityIds - Identity involved in this quicklink
sessionowner - Sessnion Owner
workflowName - WorkFlow which is getting trigger once we invoke the quicklink
trace - Logger for tracking
transient - Transient

Saturday, December 14, 2019

Sailpoint IIQ Quicklink Launch Workflow showing Form Value

Sailpoint IIQ Quicklink Launch Workflow showing Form Value

1. Create a quick link make sure the below category is created follow the step from the previous post

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE QuickLink PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<QuickLink action="workflow" category="Service Account Management" messageKey="Manage Service Account" name="Service Account View QuickLink">
  <Attributes>
    <Map>
      <entry key="workflowName" value="Service Account View Workflow"/>
    </Map>
  </Attributes>
  <Description>QuickLink to View Service Account in IIQ table</Description>
  <QuickLinkOptions allowSelf="true">
    <DynamicScopeRef>
      <Reference class="sailpoint.object.DynamicScope" name="Self Service"/>
    </DynamicScopeRef>
  </QuickLinkOptions>
</QuickLink>










2.Import the form created in the previous post

3.import the below Workflow

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Workflow PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Workflow explicitTransitions="true" name="Service Account View Workflow">
  <Variable editable="true" input="true" name="launcher">
    <Description>Launcher name.</Description>
  </Variable>
  <Variable initializer="true" name="transient"/>
  <Variable initializer="true" name="trace">
    <Description>Used for debugging this workflow and when set to true trace
      will be sent to stdout.</Description>
  </Variable>
  <Step icon="Start" name="Start" posX="229" posY="21">
    <Transition to="Display Form"/>
  </Step>
  <Step icon="Approval" name="Display Form" posX="427" posY="21">
    <Approval mode="serial" name="Display Form" owner="ref:launcher">
      <Arg name="workItemType" value="Approval"/>
      <Arg name="workItemDescription" value="Service Account Details"/>
      <Arg name="workItemForm" value="string:Service Account Details Form"/>
      <Arg name="workItemFormBasePath"/>
    </Approval>
    <Description>
       Display the Service Account form .
    </Description>
    <Transition to="Stop"/>
  </Step>
  <Step icon="Stop" name="Stop" posX="611" posY="21"/>
</Workflow>










Thursday, December 12, 2019

Active Directory Authentication Error Codes

When authentication fails while using Active Directory , Active Directory returns its own error codes to indicate 
the reason for the failure; you must retrieve and handle or display these errors appropriately. 

Below are some of the most common errors you may receive, including example error messages and reasons for the error.
525 - user not found
52e - invalid credentials
530 - not permitted to logon at this time
532 - password expired
533 - account disabled
701 - account expired
773 - user must reset password
775 - account locked

525 - user not found - 
Returned when an invalid username is supplied.
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 525, v893
HEX: 0x525 - user not found
DEC: 1317 - ERROR_NO_SUCH_USER (The specified account does not exist.)

52e - invalid credentials
Returned when a valid username is supplied but an invalid password/credential is supplied. If this error is received, 
it will prevent most other errors from being displayed
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 52e, v893
HEX: 0x52e - invalid credentials
DEC: 1326 - ERROR_LOGON_FAILURE (Logon failure: unknown user name or bad password.)

530 - not permitted to logon at this time
Returned when a valid username and password/credential are supplied during times when login is restricted.
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 530, v893
HEX: 0x530 - not permitted to logon at this time
DEC: 1328 - ERROR_INVALID_LOGON_HOURS (Logon failure: account logon time restriction violation.

531 - not permitted to logon from this workstation
Returned when a valid username and password/credential are supplied, but the user is restricted from using the workstation 
where the login was attempted.
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 531, v893
HEX: 0x531 - not permitted to logon from this workstation
DEC: 1329 - ERROR_INVALID_WORKSTATION (Logon failure: user not allowed to log on to this computer.)
LDAP[userWorkstations: <multivalued list of workstation names>]
 
 
532 - password expired
Returned when a valid username is supplied, and the supplied password is valid but expired.
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 532, v893
HEX: 0x532 - password expired
DEC: 1330 - ERROR_PASSWORD_EXPIRED (Logon failure: the specified account password has expired.)
LDAP[userAccountControl: <bitmask=0x00800000>] - PASSWORDEXPIRED

533 - account disabled
Returned when a valid username and password/credential are supplied but the account has been disabled.
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 533, v893
HEX: 0x533 - account disabled
DEC: 1331 - ERROR_ACCOUNT_DISABLED (Logon failure: account currently disabled.)
LDAP[userAccountControl: <bitmask=0x00000002>] - ACCOUNTDISABLE

701 - account expired
Returned when a valid username and password/credential are supplied but the account has expired.
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 701, v893
HEX: 0x701 - account expired
DEC: 1793 - ERROR_ACCOUNT_EXPIRED (The user's account has expired.)
LDAP[accountExpires: <value of -1, 0, or extemely large value indicates account will not expire>] - ACCOUNTEXPIRED

773 - user must reset password
Returned when a valid username and password/credential are supplied, but the user must change their password immediately
(before logging in for the first time, or after the password was reset by an administrator).
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 773, v893
HEX: 0x773 - user must reset password
DEC: 1907 - ERROR_PASSWORD_MUST_CHANGE (The user's password must be changed before logging on the first time.)
LDAP[pwdLastSet: <value of 0 indicates admin-required password change>] - MUST_CHANGE_PASSWD

775 - account locked out
Returned when a valid username is supplied, but the account is locked out. Note that this error will be returned regardless 
of whether or not the password is invalid.
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 775, v893
HEX: 0x775 - account locked out
DEC: 1909 - ERROR_ACCOUNT_LOCKED_OUT (The referenced account is currently locked out and may not be logged on to.)
LDAP[userAccountControl: <bitmask=0x00000010>] - LOCKOUT

Sailpoint IIQ Form - Reading Value from IIQ Database


Below is the sample Form in which most of the value of the field is read from the IIQ Custom 
Table DB . in the previous posts we have seen the sample code for reading the data from IIQ Database.
Create a Table in IIQ Database name VIS_SERVICE_ACCOUNT with below fields

ACCOUNT_ID
APPLICATION_NAME
ACCOUNT_DESCRIPTION
OWNER
INTERACTIVE


    
    
    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE Form PUBLIC "sailpoint.dtd" "sailpoint.dtd">
    <Form name="Service Account Details Form" type="Workflow">
      <Attributes>
        <Map>
          <entry key="pageTitle" value="Service Account Details Form"/>
        </Map>
      </Attributes>
      <Section>
        <Field displayName="Account Identifier" helpKey="Account ID of Service Account" name="accountID" postBack="true" required="true" type="string">
          <AllowedValuesDefinition>
            <Script>
              <Source>
       import sailpoint.tools.Util;
       import sailpoint.tools.GeneralException;
       import org.apache.log4j.Logger;
    
       Logger logger= Logger.getLogger("vis.form.ServiceAccount.fields");
    
       List itemList = new ArrayList();
                
       try{
    
       String  columnSearch = "ACCOUNT_ID";
       String  tableName = "VIS_SERVICE_ACCOUNT";
       String  conditionColumnName = "ACCOUNT_ID";
       String  sqlStatement ="select "+columnSearch+" from "+tableName;
       Iterator it = context.search("sql:"+sqlStatement, null,null);
    
        while ((null != it) &amp;&amp; it.hasNext()) {
          String i= it.next();
          if(!itemList.contains(i)) {
           itemList.add(i);
          }
        }
       Util.flushIterator(it);
       }
       catch(GeneralException ex){
        logger.error("Error in AppEdit form : " +ex.getMessage());
       }
       return itemList;
              </Source>
            </Script>
          </AllowedValuesDefinition>
        </Field>
        <Field displayName="Application Name" displayType="combobox" helpKey="Application Name of the Service Account" name="applicationName" postBack="true" required="true" type="string">
          <AllowedValuesDefinition>
            <Script>
              <Source>
       import sailpoint.tools.Util;
       import sailpoint.tools.GeneralException;
       import org.apache.log4j.Logger;
    
       Logger logger= Logger.getLogger("vis.form.ServiceAccount.fields");
       List itemList = new ArrayList();
                
       try{
    
       String  columnSearch = "APPLICATION_NAME";
       String  tableName = "VIS_SERVICE_ACCOUNT";
       String  conditionColumnName = "ACCOUNT_ID";
       String  sqlStatement ="select "+columnSearch+" from "+tableName + " where ACCOUNT_ID ='"+ accountID + "'";
                System.out.println("sqlStatement = " + sqlStatement);
       Iterator it = context.search("sql:"+sqlStatement, null,null);
    
        while ((null != it) &amp;&amp; it.hasNext()) {
          String i= it.next();
          itemList.add(i);
        }
       Util.flushIterator(it);
       }
       catch(GeneralException ex){
        logger.error("Error in AppEdit form : " +ex.getMessage());
       }
       return itemList;
              </Source>
            </Script>
          </AllowedValuesDefinition>
          <Attributes>
            <Map>
              <entry key="hidden">
                <value>
                  <Script>
                    <Source>if(accountID==null || accountID ==void){
                      return true;
                    }</Source>
                  </Script>
                </value>
              </entry>
            </Map>
          </Attributes>
        </Field>
        <Field displayName="Account Description" dynamic="true" helpKey="Description of Service Account" name="accountDescription" type="string">
          <Attributes>
            <Map>
              <entry key="hidden">
                <value>
                  <Script>
                    <Source>if(accountID==null || accountID ==void || applicationName==null || applicationName ==void){
                      return true;
                    }</Source>
                  </Script>
                </value>
              </entry>
              <entry key="readOnly" value="true"/>
            </Map>
          </Attributes>
          <Script>
            <Source>
              if(accountID!=null){
         String  columnSearch = "ACCOUNT_DESCRIPTION";
         String  tableName = "VIS_SERVICE_ACCOUNT";
         String  conditionColumnName = "ACCOUNT_ID";
         String  sqlStatement ="select "+columnSearch+" from "+tableName+" where "+conditionColumnName+"='"+accountID+"'"+" and APPLICATION_NAME ='"+applicationName+"'";
         Iterator  itr = context.search("sql:"+sqlStatement, null,null);
         while(itr.hasNext()){
          String accountDescription =  itr.next();
          if(accountDescription!=null){
         return accountDescription;
          }
         }
             }
            </Source>
          </Script>
        </Field>
        <Field displayName="Account Owner" dynamic="true" helpKey="Owner of the Service Account" name="owner" type="sailpoint.object.Identity">
          <Attributes>
            <Map>
              <entry key="hidden">
                <value>
                  <Script>
                    <Source>if(accountID==null || accountID ==void || applicationName==null || applicationName ==void){
                      return true;
                    }</Source>
                  </Script>
                </value>
              </entry>
              <entry key="readOnly" value="true"/>
            </Map>
          </Attributes>
          <Script>
            <Source>         
            if(accountID!=null){
         String  columnSearch = "OWNER";
         String  tableName = "VIS_SERVICE_ACCOUNT";
         String  conditionColumnName = "ACCOUNT_ID";
         String  sqlStatement ="select "+columnSearch+" from "+tableName+" where "+conditionColumnName+"='"+accountID+"'"+" and APPLICATION_NAME ='"+applicationName+"'";
         Iterator  itr = context.search("sql:"+sqlStatement, null,null);
         while(itr.hasNext()){
          String owner =  itr.next();
          if(owner!=null){
         return owner;
          }
         }
              }</Source>
          </Script>
        </Field>
        <Field displayName="Interactive" dynamic="true" helpKey="Service Account is Interactive or Non-Interactive" name="interactive" type="string">
          <AllowedValuesDefinition>
            <Value>
              <List>
                <String>Yes</String>
                <String>No</String>
              </List>
            </Value>
          </AllowedValuesDefinition>
          <Attributes>
            <Map>
              <entry key="hidden">
                <value>
                  <Script>
                    <Source>if(accountID==null || accountID ==void || applicationName==null || applicationName ==void){
                      return true;
                    }</Source>
                  </Script>
                </value>
              </entry>
              <entry key="readOnly" value="true"/>
            </Map>
          </Attributes>
          <Script>
            <Source>
              if(accountID!=null){
         String  columnSearch = "INTERACTIVE";
         String  tableName = "VIS_SERVICE_ACCOUNT";
         String  conditionColumnName = "ACCOUNT_ID";
         String  sqlStatement ="select "+columnSearch+" from "+tableName+" where "+conditionColumnName+"='"+accountID+"'"+" and APPLICATION_NAME ='"+applicationName+"'";
         Iterator  itr = context.search("sql:"+sqlStatement, null,null);
         while(itr.hasNext()){
          String interactive =  itr.next();
          if(interactive!=null){
         return interactive;
          }
         }
              }
            </Source>
          </Script>
        </Field>
      </Section>
      <Button action="back" label="Cancel"/>
    </Form>