Announcing the Saviynt Knowledge Exchange unifying the Saviynt forums, documentation, training,
and more in a single search tool across platforms. Read the announcement here.

LDAP Connector - Update Account - Unable to remove value from multivalued attribute

kunal_saxena
Regular Contributor
Regular Contributor

Hi,

We have onboarded a LDAP application using the LDAP/AD connector. In LDAP, there is a multivalued attribute - nsRoleDN which is used to manage directory roles assigned to users. Our requirement is to manage these roles from Saviynt. Therefore, we need to modify the nsRoleDN multivalued attribute from Saviynt. In case assigning a new role, we should add a new value to this attribute and in case of role removal, we should remove an existing value.

We are able to add a new role from Saviynt by passing the new role value against the "nsRoleDN" attribute in UpdateAccountJSON. Example: {"nsRoleDN": "Role A"}. A new value for nsRoleDN gets appended in the target LDAP.

However, we are unable to remove an existing value. For example, if a user has 3 roles - Role A, Role B & Role C. If we need to remove Role C, we are trying to pass nsRoleDN value as - "nsRoleDN": ["Role A", "Role B"] in the UpdateAccountJSON. The update account task fails with the following error: "Error while Update operation for account-username in AD - [LDAP: error code 20 - Attribute Or Value Exists]"

Can you please help as to how we can remove an existing value from this multi-valued attribute, i.e., nsRoleDN using UpdateAccountJSON?

Thanks,
Kunal

3 REPLIES 3

SB
Saviynt Employee
Saviynt Employee

Can you share the update account JSON you are using. Also, if you could share the log for 1 task.


Regards,
Sahil

kunal_saxena
Regular Contributor
Regular Contributor

Hi @SB ,

Please find below the Update Account JSON and logs:

Update Account JSON:

{
"givenName": "${user.firstname}",
"sn": "${if(user.lastname != null){user?.lastname.trim()} else {''}}",
"cn": "${if(user.displayname != null && user.displayname != ''){user?.displayname.trim()} else {user.lastname+', '+user.firstname}}",
"mail": "${if(user.email != null){user?.email.trim()} else {''}}",
"title": "${if(user.title != null){user?.title.trim()} else {''}}",
"l": "${if(user.city != null){user?.city.trim()} else {''}}",
"st": "${if(user.state != null){user?.state.trim()} else {''}}",
"postalcode": "${if(user.location != null){user?.location.trim()} else {''}}",
"c": "${if(user.country != null){user?.country.trim()} else {''}}",
"street": "${if(user.street != null){user?.street.trim()} else {''}}",
"nsRoleDN": ["${task?.accountKey.customproperty20}"]
}

Logs:

2023-11-02T08:34:36.268+00:00ecm-workerldap.SaviyntGroovyLdapServicequartzScheduler_Worker-4-pwvtfERRORError Updating the Account from AD - [LDAP: error code 20 - Attribute Or Value Exists]
2023-11-02T08:34:37.170+00:00ecm-workernull-pwvtfjavax.naming.directory.AttributeInUseException: [LDAP: error code 20 - Attribute Or Value Exists]; remaining name 'uid=T3080294,ou=users,o=abc.com' at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3245) at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3207) at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2998) at com.sun.jndi.ldap.LdapCtx.c_modifyAttributes(LdapCtx.java:1503) at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_modifyAttributes(ComponentDirContext.java:277) at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.modifyAttributes(PartialCompositeDirContext.java:192) at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.modifyAttributes(PartialCompositeDirContext.java:181) at javax.naming.directory.InitialDirContext.modifyAttributes(InitialDirContext.java:167) at com.saviynt.ldap.SaviyntGroovyLdapService.updateLDAPAccount(SaviyntGroovyLdapService.groovy:7237) at com.saviynt.ldap.SaviyntGroovyLdapService$_updateAccountGLDAP_closure7.doCall(SaviyntGroovyLdapService.groovy:2653) at com.saviynt.ldap.SaviyntGroovyLdapService.updateAccountGLDAP(SaviyntGroovyLdapService.groovy:2224) at com.saviynt.ecm.services.ArsTaskService.updateAccountTarget(ArsTaskService.groovy:11306) at com.saviynt.ecm.services.ArsTaskHelperService$_whenTaskTypeIsTwelveUpdateAccount_closure46.doCall(ArsTaskHelperService.groovy:2877) at com.saviynt.ecm.services.ArsTaskHelperService.whenTaskTypeIsTwelveUpdateAccount(ArsTaskHelperService.groovy:2867) at com.saviynt.ecm.services.ArsTaskHelperService$_completeAutoProvTasksUpgraded_closure1.doCall(ArsTaskHelperService.groovy:200) at com.saviynt.ecm.services.ArsTaskHelperService.completeAutoProvTasksUpgraded(ArsTaskHelperService.groovy:160) at MultipleProvisioningJob.execute(MultipleProvisioningJob.groovy:222) at org.quartz.core.JobRunShell.run(JobRunShell.java:199) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:546)
2023-11-02T08:34:36.270+00:00ecm-workerldap.SaviyntGroovyLdapServicequartzScheduler_Worker-4-pwvtfDEBUGExit updateAccountGLDAP
2023-11-02T08:34:36.270+00:00ecm-workerservices.ArsTaskServicequartzScheduler_Worker-4-pwvtfDEBUGInside updateProvisioningTries..
2023-11-02T08:34:36.293+00:00ecm-workerservices.ArsTaskServicequartzScheduler_Worker-4-pwvtfDEBUGEntering provisionAccesstoAccountSaviynt
2023-11-02T08:34:36.293+00:00ecm-workerservices.ArsTaskServicequartzScheduler_Worker-4-pwvtfDEBUG{T3080294=[]}
2023-11-02T08:34:36.293+00:00ecm-workerservices.ArsTaskServicequartzScheduler_Worker-4-pwvtfDEBUGUPDATEACCOUNT

SB
Saviynt Employee
Saviynt Employee

Can you share the complete log file instead. I will need to check from the payload info and see how saviynt is updating the value. Run the provisioning job for 1 task and capture the log from the job start time.


Regards,
Sahil