Sync AD attribute accountExpires with IDM / DirXML to W2K3 server

(Last modified: 04Sep2005)

This document (10095847) is provided subject to the disclaimer at the end of this document.

goal

Sync AD attribute accountExpires with IDM / DirXML to W2K3 server

fact

idm201adir3.exe

ADDriver from idm201adir3.exe

AD attribute accountExpires

Windows 2003 server

W2K3 AD server, Active Directory

eDirectory attribute Login Expiration Time

IDM 2.0.1

Nsure Identity Manager 2.0.1

symptom

Error "LDAP_UNWILLING_TO_PERFORM"

 Error when setting accountExpires

 Status: Error
Message: <ldap-err ldap-rc="20" ldap-rc-name="LDAP_ATTRIBUTE_OR_VALUE_EXISTS">
   <client-err ldap-rc="20" ldap-rc-name="LDAP_ATTRIBUTE_OR_VALUE_EXISTS">Attribute Or Value Exists</client-err>
   <server-err>0000207E: AtrErr: DSID-03190616, #1:
   0: 0000207E: DSID-03190616, problem 1006 (ATT_OR_VALUE_EXISTS), data 0, Att 9009f (accountExpires)
</server-err>
   <server-err-ex win32-rc="8318"/>
</ldap-err>

 Error when disabling accountExpires

Status: Error
Message: <ldap-err ldap-rc="21" ldap-rc-name="LDAP_INVALID_SYNTAX">
   <client-err ldap-rc="21" ldap-rc-name="LDAP_INVALID_SYNTAX">Invalid Syntax</client-err>
   <server-err>00000057: LdapErr: DSID-0C0909CC, comment: Error in attribute conversion operation, data 0, vece</server-err>
   <server-err-ex win32-rc="87"/>
</ldap-err>

fix

The original Time Conversion Style Sheet for the AD driver, produces errors when trying to sync accountExpires.  The fix is to use the Style Sheet below:

Note: if you are missing the original Time Conversion Style Sheet, then Reinstall your Active Directory Driver with the current ACTIVEDIRECTORY.XML code from http://support.novell.com/filefinder/.   The Time Conversion Style Sheet is built into a default install of the Active Directory Driver.   If you are missing the Time Conversion Stylesheets,  then you need to reinstall your Active Directory Driver to get them back.

Replace the OLD TimeConversion Style Sheet found in the Output Transformation Policies, with this:

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet exclude-result-prefixes="madutil" version="1.0" xmlns:madutil="http://www.novell.com/nxsl/java/com.novell.nds.dirxml.driver.ad.util.Utilities" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <!-- parameters passed in from the DirXML engine -->
 <xsl:param name="fromNds"/>
 <!-- With this policy, eDir attributes using the Time syntax (a 32 bit integer -->
 <!-- representing time since jan 1, 1970) are converted to the Active Directory-->
 <!-- Interval syntax (a 64 bit integer representing time since Jan 1, 1601).   -->
 <!-- Add a default value on an add  from edirectory -->
 <!-- Daniel Kresge replaced -1 with 0 -->
 <xsl:template match="add[@class-name='user' and not(add-attr[@attr-name='accountExpires'])]">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
   <xsl:if test="$fromNds">
    <add-attr attr-name="accountExpires">
     <value type="string">0</value>
    </add-attr>
   </xsl:if>
  </xsl:copy>
 </xsl:template>
 <!-- Drop any remove value -->
 <xsl:template match="modify-attr[@attr-name='accountExpires' or @attr-name='lockoutTime']/remove-value"/>
 <!-- Add the remove-all-values if not present, add a default value if not present -->
 <xsl:template match="modify-attr[@attr-name='accountExpires' or @attr-name='lockoutTime']">
  <xsl:copy>
   <xsl:apply-templates select="@*"/>
   <xsl:if test="not(remove-all-values)">
    <remove-all-values/>
   </xsl:if>
   <xsl:apply-templates select="node()"/>
   <xsl:if test="$fromNds and not(add-value)">
    <add-value>
     <value type="string">0</value>
    </add-value>
   </xsl:if>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="modify-attr[@attr-name='accountExpires' or @attr-name='lockoutTime']/add-value[value/text()='18446744073709551615' or value/text()='0']"/>
 <!-- apply text conversion policies -->
 <xsl:template match="value[ancestor::*[@attr-name='accountExpires' or @attr-name='lockoutTime']]">
  <!-- apply filetime conversion policy -->
  <xsl:variable name="filetime">
   <xsl:choose>
    <xsl:when test="$fromNds">
     <xsl:value-of select="madutil:translateEpoch2FileTime(text())"/>
    </xsl:when>
    <xsl:otherwise>
     <xsl:value-of select="madutil:translateFileTime2Epoch(text())"/>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:variable>
  <xsl:if test="$filetime and text()!='0' and text()!='0'">
   <value>
    <xsl:value-of select="$filetime"/>
   </value>
  </xsl:if>
 </xsl:template>
 <!-- identity transformation template -->
 <!-- in the absence of any other templates this will cause -->
 <!-- the stylesheet to copy the input through unchanged to the output -->
 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>
  

Also chain it in the Publisher on the Input Transform Policies AND you also have to remove the following from the existing Input Transform SS found in the Input Transform Policies.

<!-- apply filetime conversion policy -->
<xsl:when test="$attrname = $filetime-policy-list">
<xsl:comment>AD Interval to eDir Time translation policy</xsl:comment>
<!-- java callout performs conversion -->
        <xsl:variable name="epoch"
select="madutil:translateFileTime2Epoch(text())"/>
                   <xsl:if test="$epoch">
        <xsl:copy>
        <xsl:apply-templates select="@*"/>
          <xsl:value-of select="$epoch"/>
       </xsl:copy>
                  </xsl:if>
</xsl:when>

.

note

Background information on accountExpires:

From MSDN "The date when the account will expire. This value represents the number of 100 nanosecond intervals since January 1, 1601 (UTC). A value of -1 indicates that the account will never expire."

Also from MSDN, "To set the account expiration date, set the IADsUser.AccountExpirationDate property to the desired date value. To disable the account expiration date, set the accountExpires attribute to zero."

Testing shows that setting accountExpires to "0" with IDM is successful, using an LDAP editor to set accountExpires to "0" also works.  Using "-1" as indicated in the first MSDN link above, did not work.

Behavior:

In Active Directory (AD) using Active Directory Users and Computers, new users are created with the accountExpires attribute shown as "Account expires" on the user under the Account tab, set to "Never" with a grayed out date.  This same new user when viewed with LDAP Browser/Editor will display accountExpires as "9223372036854775807" viewed with LDP.EXE it will show as "accountExpires: 09/14/30828 02:48:05 UNC ;"

When using Active Directory Users and Computers under user properties |  Account | Account expires,  checking the radio button "End of", enables the date field, at the end of the date entered, the account will expire.

After "End of" has been set once, if using Active Directory Users and Computers to set accountExpires back to "Never," when viewed with LDAP Browser/Editor will display accountExpires as "0" viewed with LDP.EXE it will show as "accountExpires: 01/01/1601 00:00:00 UNC ;"

One thing that is odd about this attribute is that the raw value represents the number of 100 nanosecond intervals since January 1, 1601 (UTC), yet AD Users and Computers only allows expiration to be "End of" a given day.  Here is a time converter that will convert nanoseconds to days, months, years or even fortnights if you prefer.

document

Document Title: Sync AD attribute accountExpires with IDM / DirXML to W2K3 server
Document ID: 10095847
Solution ID: NOVL100079
Creation Date: 13Dec2004
Modified Date: 04Sep2005
Novell Product Class:DirXML

disclaimer

The Origin of this information may be internal or external to Novell. Novell makes all reasonable efforts to verify this information. However, the information provided in this document is for your information only. Novell makes no explicit or implied claims to the validity of this information.
Any trademarks referenced in this document are the property of their respective owners. Consult your product manuals for complete trademark information.