wt.org
Class WTUserAndGroupToLDAPMigrator

java.lang.Object
  extended bywt.org.WTUserAndGroupToLDAPMigrator
All Implemented Interfaces:
Migrator

public class WTUserAndGroupToLDAPMigrator
extends Object
implements Migrator

Migration strategy: +) WTUser and WTGroup: .) values will be moved to the specified Directory. .) For LDAP users, the wtuser already exists in the Directory. The dn will be obtained from the LDAPAttributeHolder and used for setting the dn of the member of the groups the specified user belongs to. .) a UFID will be created for every WTUser and WTGroup. +) ProxyUser and ProxyGroup: .) values will be moved to WTUser and WTGroup. .) a UFID will be created for every ProxyUser and ProxyGroup. .) the ProxyUser and ProxyGroup values will be deleted. .) all references will be updated. The above is the normal scenario. But: Prior to Windchill R6.0, the WTUser table contained a name attribute and an authenticationName attribute. The name attribute was used as the name of user's personal cabinet and was used to identify a user within Windchill user interfaces. The authenticationName attribute was the user's login name (web server ID). In Windchill R6.0 and later releases, the WTUser table no longer contains the authenticationName attribute and the name attribute contains the web server ID. The name of a user's personal cabinet needs to match the WTUser table's name attribute. If the name and authenticationName attributes have different values prior to R6.0, the migration tool needs to rename the user's personal cabinet and WTUser name to match the web Server ID. How this is to be done: There will exist 2 new properties within wt.properties: wt.federation.org.allowLDAPEntryCreation (default is true. If not specified, it will be assumed to be true) wt.federation.org.searchForGroups (default is false. If not specified, it will be assumed to be false) 1)For every WTUser, the given adapters will be searched for the WTUser web name (ie. authenticationName). The given adapters are listed in the wt.federation.org.directoryServices property within wt.properties. See the Install Guide for more information concerning configuring the JNDI Adapters. The search for users entails searching for an entry with an object class of inetOrgPerson and whose uid attribute matches the WTUser authenticationName.The search will find the search base associated with each adapter that is named in wt.federation.org.directoryServices. It will search, in order specified in wt.federation.org.directoryServices and stop at the first entry found. a) If found: this WTUser will be associated with the returned RDN. i) if the WTUser name is not the same as the web name and the WTUser name is not the Administrator user (the WTUser name attribute matching the wt.admin.defaultAdministratorName wt.properties value), then the WTUser name and cabinet name will be renamed to the web name. b) If not found: i) If wt.properties, wt.federation.org.allowLDAPEntryCreation, is false, then the migrator tool will exit with an Error AFTER ALL LOCAL USERS AND GROUPS ARE SEARCHED FOR. (For each user, the migrator tool will log a WARNING and continue. After trying to migrate all local users and groups, if one of these WARNINGs occurred, the migrator tool will stop. The site will now have a log of what users were not found in the list of Adapters stated in wt.federation.org.directoryServices and were not created. The migrator tool needs to be restarted after all the given users are created in LDAP in order for the migrator, WTUserAndGroupToLDAPMigrator, to complete successfully.) ii) If wt.federation.org.allowLDAPEntryCreation is true: The user not found will be created at the search base defined for the default adapter. The wt.federation.org.defaultAdapter property specifies the default adapter. If unable to create the user (due to not having WRITE permission), then the migrator will throw an Exception and stop. The problem needs to be fixed before continuing. 2)For the Administrator user (the WTUser name attribute matching the wt.admin.defaultAdministratorName property value): i) If web name is found (i.e. the WTUser's authenticationName), then the returned RDN is the RDN the WTUser will be associated with. The migrator will also verify that this entry has an attribute of uid=. If it does not, if wt.federation.org.allowLDAPEntryCreation is true, then it will add this attribute to the entry. If wt.federation.org.allowLDAPEntryCreation is false, then it will log this as an error and the migrator tool will exit with an Error AFTER ALL LOCAL USERS AND GROUPS ARE SEARCHED FOR. ii) If web name is not found: If wt.properties, wt.federation.org.allowLDAPEntryCreation, is false, then the migrator tool will exit with an Error AFTER ALL LOCAL USERS AND GROUPS ARE SEARCHED FOR. (For each user, the migrator tool will log a WARNING and continue. After trying to migrate all local users and groups, if one of these WARNINGs occurred, the migrator tool will stop. The site will now have a log of what users were not found in the list of Adapters stated in wt.federation.org.directoryServices and were not created. The migrator tool needs to be restarted after all the given users are created in LDAP in order for the migrator, WTUserAndGroupToLDAPMigrator, to complete successfully.) If wt.federation.org.allowLDAPEntryCreation is true: The Administrator user will be created at the search base defined for the default adapter. The wt.federation.org.defaultAdapter property specifies the default adapter. This entry will be created, with 2 uid attribute values: uid=web name (i.e, the WTUser authenticationName) and uid=WTUser name,with uid=web name as the entry's relative distinguished name (RDN). This entry, within Windchill, will have a cabinet name and WTUser name different than the web name. This will be the only user like this. If unable to create the user (due to not having WRITE permission), then the migrator will throw an Exception and stop. The problem needs to be fixed before continuing. 3) For every WTGroup: i) If the wt.properties, wt.federation.org.searchForGroups, is false: only the search base defined by the default adapter will be searched for the given Group. If found, this WTGroup will be associated with the returned RDN. ii) If the wt.properties, wt.federation.org.searchForGroups, is true: The given adapters will be searched for the WTGroup name. The given adapters are listed in the wt.federation.org.directoryServices property within wt.properties. See the Install Guide for more information concerning configuring the JNDI Adapters. The search for Group entails searching for an entry with an object class of groupOfUniqueName and whose cn attribute matches the WTGroup name. The search will find the search base associated with each adapter that is named in wt.federation.org.directoryServices. It will search, in order specified in wt.federation.org.directoryServices and stop at the first entry found. if found, this WTGroup will be associated with the returned RDN. iii) If Group not found: If wt.properties, wt.federation.org.allowLDAPEntryCreation, is false, then the migrator tool will exit with an Error AFTER ALL LOCAL USERS AND GROUPS ARE SEARCHED FOR. (For each user and group, the migrator tool will log a WARNING and continue. After trying to migrate all local users and groups, if one of these WARNINGs occurred, the migrator tool will stop. The site will now have a log of what * users were not found in the list of Adapters stated in wt.federation.org.directoryServices and were not created. The migrator tool needs to be restarted after all the given users are created in LDAP in order for the migrator, WTUserAndGroupToLDAPMigrator, to complete successfully.) If wt.federation.org.allowLDAPEntryCreation is true: The specified Group will be created at the search base defined for the default adapter. The wt.federation.org.defaultAdapter property specifies the default adapter. If unable to create the group (due to not having WRITE permission), then the migrator will throw an Exception and stop. The problem needs to be fixed before continuing.


Field Summary
private static String adminAdapter
           
private static boolean allowCreation
           
private  Connection connection
           
private  PrintWriter debugLog
           
private static String defaultDirectoryUser
           
private static String DIRECTORY_SERVICES
           
private static boolean DIRVERBOSE
           
private static boolean DISABLE_PRINCIPALS
           
private static Hashtable groupAdapters
           
private static Hashtable groupNameHash
           
private static String ieldapServer
           
private static String KEY_CLASSNAME
           
private static String KEY_ID
           
private static int MAX_IN_CLAUSE_SIZE
           
private  Hashtable objectMappablesWithRefs
           
private static int ORA_UNIQUE_CONSTRAINT
           
private static Hashtable proxyGroupHash
           
private  Vector ProxyGroupOidLists_
           
private static Hashtable proxyUserHash
           
private  Vector ProxyUserOidLists_
           
private static long reposida2a2
           
private static String RESOURCE
           
private static boolean searchForGroups
           
private static Vector serviceVector
           
private  Vector unableToCreateNewEntry
           
private  Vector unableToLocateProxyPrincipals
           
private  Vector uniquenessError
           
private static Hashtable userNameHash
           
 
Constructor Summary
WTUserAndGroupToLDAPMigrator()
           
 
Method Summary
private  void addGroupToLDAP(String groupName, String groupDesc, String groupCnAtt, String adapter)
          Add the Group to the Directory.
private  void addMembersToLocalGroup()
          Find all the members of a local group and add to Group's LDAP.
 String addToAddr(String totalAddress, String addrpart)
          create Address
static void addUserToLDAP(String userName, String fullName, String basedn, Vector attslist, String userIdAtt, String adapter)
          Add user to Directory
static void addUserToWebUser(String name, String basedn, String adapter)
          Add Admin user to Web User in the Directory
static void addWebUserToUser(String name, String basedn, String adapter)
          Add Admininstrator Web User to Administrator User in the Directory
private  void breakOidListIntoManageableSets(Vector user_oid_list, Vector oidLists_)
          Ugly method to cope with the fact that Oracle can only handle so many elements in a SQL IN(...) list.
private  void buildObjectMappablesList()
          Build a list of ObjectMappable classes with reference properties that may contain a WTPrincipalReference.
private  void changeNamesToAuthenticationName(String userName, String authenticationName, long oid)
          Change the cabinet name and wtuser name to match the authenticatioName of the WTUser since this is the key being used for authenticating against the Directory.
private  String createAdminUser(String webUserName, String userName, long oid, AttributeHolder atts)
          create Admin user
private  void createProxyUfid(long proxyreposida2a2, String oid, String className, String idName, String dn)
          createProxyUfid for proxyusers and proxygroups
private  void createUfid(long reposOid, long oid, String className, String userIdName, String dn)
          createUfid
static void dirInit()
          initialize.
private  StringBuffer escapeName(String userName)
          Given the incoming name, escape it.
private  void findOidsofProxyGroupToTurnIntoWTGroup()
          Find oids of all the users that have to be turned into ProxyUsers.
private  void findOidsofProxyUserToTurnIntoWTUser()
          Find oids of all the users that have to be turned into ProxyUsers.
private  Enumeration getAllMigrationServices()
           
private  void listReferenceProperties(ClassInfo class_info, EnumeratorVector vect, String property_name)
           
private  void moveProxyGroupToWTGroup()
          Move Proxy Group to WTGroup.
private  void moveProxyUserToWTUser()
          Move Proxy Users To WTUsers and delete Proxy Users.
private  String queryGroup(String groupName)
          Query for a group definition registered in the directory.
private  String queryProxyGroup(String groupName, String adapter)
          Query for a proxyGroup definition registered in the directory.
private  String queryProxyUser(String userName, String adapter)
          Query a proxyUser definition registered in the directory.
private  String queryUser(String userName)
          Query a user definition registered in the directory.
 boolean runMigration(Connection connection_, PersistentObjectManager pom, PrintWriter logWriter)
          Run the migration.
private static void safeClose(ResultSet rs)
          If the Statement is not null, try to close it, catching and smothering any IOException that results.
private static void safeClose(Statement stmt)
          If the Statement is not null, try to close it, catching and smothering any IOException that results.
private  Vector setupLocalUsersAttributes(AttributeHolder atts, String adapter)
           
private  void updateLocalGroups()
          Find all the local groups in the database.
private  void updateLocalUsers()
          Find all the local users in the database.
private  void updateReferencesThatAreProperties(ClassInfo class_info)
           
private  void updateReferencesThatArePropertiesOnPersistables()
           
private  void updateReferenceToUserAndGroup(BaseTableInfo bti, ColumnDescriptor cls_name_col, ColumnDescriptor id_name_col)
          Change the classname for migrated users from ProxyUser to WTUser, for references with the specified table and pair of reference columns.
private  long updateRepository(String location)
          Update Repository.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ORA_UNIQUE_CONSTRAINT

private static final int ORA_UNIQUE_CONSTRAINT
See Also:
Constant Field Values

MAX_IN_CLAUSE_SIZE

private static final int MAX_IN_CLAUSE_SIZE
See Also:
Constant Field Values

KEY_CLASSNAME

private static final String KEY_CLASSNAME
See Also:
Constant Field Values

KEY_ID

private static final String KEY_ID
See Also:
Constant Field Values

RESOURCE

private static final String RESOURCE
See Also:
Constant Field Values

adminAdapter

private static String adminAdapter

allowCreation

private static boolean allowCreation

debugLog

private PrintWriter debugLog

defaultDirectoryUser

private static String defaultDirectoryUser

DIRVERBOSE

private static boolean DIRVERBOSE

DISABLE_PRINCIPALS

private static boolean DISABLE_PRINCIPALS

ieldapServer

private static String ieldapServer

reposida2a2

private static long reposida2a2

searchForGroups

private static boolean searchForGroups

serviceVector

private static Vector serviceVector

DIRECTORY_SERVICES

private static String DIRECTORY_SERVICES

connection

private Connection connection

groupNameHash

private static Hashtable groupNameHash

proxyGroupHash

private static Hashtable proxyGroupHash

groupAdapters

private static Hashtable groupAdapters

proxyUserHash

private static Hashtable proxyUserHash

userNameHash

private static Hashtable userNameHash

ProxyGroupOidLists_

private Vector ProxyGroupOidLists_

ProxyUserOidLists_

private Vector ProxyUserOidLists_

unableToCreateNewEntry

private Vector unableToCreateNewEntry

uniquenessError

private Vector uniquenessError

unableToLocateProxyPrincipals

private Vector unableToLocateProxyPrincipals

objectMappablesWithRefs

private Hashtable objectMappablesWithRefs
Constructor Detail

WTUserAndGroupToLDAPMigrator

public WTUserAndGroupToLDAPMigrator()
Method Detail

dirInit

public static void dirInit()
                    throws WTException,
                           IOException,
                           IEException
initialize.

Supported API: true

Throws:
WTException
IOException
IEException

runMigration

public boolean runMigration(Connection connection_,
                            PersistentObjectManager pom,
                            PrintWriter logWriter)
                     throws SQLException,
                            IOException,
                            ClassNotFoundException,
                            WTException,
                            IEException
Description copied from interface: Migrator
Run the migration.

Migrators should log all output to the given PrintWriter. This is the log that is created by RunMigrators. It is an autoflush writer.

Migrators should return true if they successfully completed migration and false otherwise. It is the migrator's responsibility to log failure reasons to the log.

Migrators should not concern themselves with committing the work on the connection. The MigratorRunner will commit the connection work after running each Migrator.

Specified by:
runMigration in interface Migrator
Parameters:
connection_ - an open connection to the Windchill database
pom - a persistent object manager against the Windchill database
logWriter - an autoflush printwriter for logging any and all output
Throws:
SQLException
IOException
ClassNotFoundException
WTException
IEException

updateLocalUsers

private void updateLocalUsers()
                       throws SQLException,
                              IOException,
                              ClassNotFoundException,
                              DatastoreException,
                              WTException,
                              IEException
Find all the local users in the database. These need to be added to the Directory and a UFID created.

Throws:
SQLException
IOException
ClassNotFoundException
DatastoreException
WTException
IEException

setupLocalUsersAttributes

private Vector setupLocalUsersAttributes(AttributeHolder atts,
                                         String adapter)
                                  throws WTException,
                                         IOException,
                                         IEException
Throws:
WTException
IOException
IEException

updateLocalGroups

private void updateLocalGroups()
                        throws SQLException,
                               IOException,
                               WTException,
                               DatastoreException,
                               IEException
Find all the local groups in the database. These need to be added to the Directory.

Throws:
SQLException
IOException
WTException
DatastoreException
IEException

addMembersToLocalGroup

private void addMembersToLocalGroup()
                             throws SQLException,
                                    IOException,
                                    WTException,
                                    DatastoreException,
                                    IEException
Find all the members of a local group and add to Group's LDAP. The groupuserlink gives this information: ida3a5 represents the ida2a2 of the group and ida3b5 of the user.

Throws:
SQLException
IOException
WTException
DatastoreException
IEException

moveProxyUserToWTUser

private void moveProxyUserToWTUser()
                            throws SQLException,
                                   IOException,
                                   WTException,
                                   DatastoreException,
                                   IEException
Move Proxy Users To WTUsers and delete Proxy Users.

Throws:
SQLException
IOException
WTException
DatastoreException
IEException

moveProxyGroupToWTGroup

private void moveProxyGroupToWTGroup()
                              throws SQLException,
                                     IOException,
                                     WTException,
                                     DatastoreException,
                                     IEException
Move Proxy Group to WTGroup. Need to obtain source info from database to create a ufid

Throws:
SQLException
IOException
WTException
DatastoreException
IEException

addUserToLDAP

public static void addUserToLDAP(String userName,
                                 String fullName,
                                 String basedn,
                                 Vector attslist,
                                 String userIdAtt,
                                 String adapter)
                          throws IOException,
                                 IEException,
                                 WTException
Add user to Directory

Throws:
IOException
IEException
WTException

addUserToWebUser

public static void addUserToWebUser(String name,
                                    String basedn,
                                    String adapter)
                             throws IOException,
                                    IEException,
                                    WTException
Add Admin user to Web User in the Directory

Throws:
IOException
IEException
WTException

addWebUserToUser

public static void addWebUserToUser(String name,
                                    String basedn,
                                    String adapter)
                             throws IOException,
                                    IEException,
                                    WTException
Add Admininstrator Web User to Administrator User in the Directory

Throws:
IOException
IEException
WTException

updateRepository

private long updateRepository(String location)
                       throws SQLException,
                              IOException,
                              WTException,
                              DatastoreException,
                              IEException
Update Repository. First, see if Repository exists. If not, then create it. Assumptions: the local repository is created elsewhere.

Throws:
SQLException
IOException
WTException
DatastoreException
IEException

createUfid

private void createUfid(long reposOid,
                        long oid,
                        String className,
                        String userIdName,
                        String dn)
                 throws IOException,
                        WTException,
                        DatastoreException,
                        IEException,
                        SQLException
createUfid

Throws:
IOException
WTException
DatastoreException
IEException
SQLException

createProxyUfid

private void createProxyUfid(long proxyreposida2a2,
                             String oid,
                             String className,
                             String idName,
                             String dn)
                      throws IOException,
                             WTException,
                             DatastoreException,
                             IEException,
                             SQLException
createProxyUfid for proxyusers and proxygroups

Throws:
IOException
WTException
DatastoreException
IEException
SQLException

addGroupToLDAP

private void addGroupToLDAP(String groupName,
                            String groupDesc,
                            String groupCnAtt,
                            String adapter)
                     throws WTException,
                            IOException,
                            IEException
Add the Group to the Directory.

Throws:
WTException
IOException
IEException

addToAddr

public String addToAddr(String totalAddress,
                        String addrpart)
create Address


findOidsofProxyUserToTurnIntoWTUser

private void findOidsofProxyUserToTurnIntoWTUser()
                                          throws SQLException,
                                                 IOException,
                                                 WTException,
                                                 DatastoreException,
                                                 IEException
Find oids of all the users that have to be turned into ProxyUsers. We don't need to renumber them because oids are unique across all classes.

Throws:
SQLException
IOException
WTException
DatastoreException
IEException

findOidsofProxyGroupToTurnIntoWTGroup

private void findOidsofProxyGroupToTurnIntoWTGroup()
                                            throws SQLException,
                                                   IOException,
                                                   WTException,
                                                   ClassNotFoundException,
                                                   DatastoreException,
                                                   IEException
Find oids of all the users that have to be turned into ProxyUsers. We don't need to renumber them because oids are unique across all classes.

Throws:
SQLException
IOException
WTException
ClassNotFoundException
DatastoreException
IEException

breakOidListIntoManageableSets

private void breakOidListIntoManageableSets(Vector user_oid_list,
                                            Vector oidLists_)
Ugly method to cope with the fact that Oracle can only handle so many elements in a SQL IN(...) list. It breaks the oid list into chuncks of MAX_IN_CLAUSE_SIZE oids and prepares them as a string formatted like
(oid1,oid2, ...,oidn)
Each of these strings is added to the returned list. The list will be stored as the member field oidLists_


buildObjectMappablesList

private void buildObjectMappablesList()
                               throws SQLException,
                                      WTIntrospectionException
Build a list of ObjectMappable classes with reference properties that may contain a WTPrincipalReference. The class name is the hash key and the value is an EnumeratorVector containing the names of the reference properties.

Throws:
SQLException
WTIntrospectionException

listReferenceProperties

private void listReferenceProperties(ClassInfo class_info,
                                     EnumeratorVector vect,
                                     String property_name)
                              throws SQLException,
                                     WTIntrospectionException
Throws:
SQLException
WTIntrospectionException

updateReferenceToUserAndGroup

private void updateReferenceToUserAndGroup(BaseTableInfo bti,
                                           ColumnDescriptor cls_name_col,
                                           ColumnDescriptor id_name_col)
                                    throws SQLException
Change the classname for migrated users from ProxyUser to WTUser, for references with the specified table and pair of reference columns.

Throws:
SQLException

updateReferencesThatArePropertiesOnPersistables

private void updateReferencesThatArePropertiesOnPersistables()
                                                      throws SQLException,
                                                             WTIntrospectionException
Throws:
SQLException
WTIntrospectionException

updateReferencesThatAreProperties

private void updateReferencesThatAreProperties(ClassInfo class_info)
                                        throws SQLException,
                                               WTIntrospectionException
Throws:
SQLException
WTIntrospectionException

queryUser

private String queryUser(String userName)
                  throws WTException
Query a user definition registered in the directory.

Parameters:
userName - The unique identifier for a user
Returns:
The distinguished name of the matching entry, or null if no matches are found.

Supported API: false
Throws:
WTException

queryGroup

private String queryGroup(String groupName)
                   throws WTException
Query for a group definition registered in the directory.

Parameters:
groupName - The unique identifier for a group
Returns:
The distinguished name of the matching entry, or null if no matches are found.

Supported API: false
Throws:
WTException

queryProxyUser

private String queryProxyUser(String userName,
                              String adapter)
                       throws WTException
Query a proxyUser definition registered in the directory.

Parameters:
userName - The unique identifier for a user
adapter - The JNDIadapter name
Returns:
The distinguished name of the matching entry, or null if no matches are found.

Supported API: false
Throws:
WTException

queryProxyGroup

private String queryProxyGroup(String groupName,
                               String adapter)
                        throws WTException
Query for a proxyGroup definition registered in the directory.

Parameters:
groupName - The unique identifier for a group
adapter - The JNDIadapter name
Returns:
The distinguished name of the matching entry, or null if no matches are found.

Supported API: false
Throws:
WTException

createAdminUser

private String createAdminUser(String webUserName,
                               String userName,
                               long oid,
                               AttributeHolder atts)
                        throws WTException
create Admin user

Throws:
WTException

changeNamesToAuthenticationName

private void changeNamesToAuthenticationName(String userName,
                                             String authenticationName,
                                             long oid)
                                      throws SQLException
Change the cabinet name and wtuser name to match the authenticatioName of the WTUser since this is the key being used for authenticating against the Directory.

Supported API: false

Throws:
SQLException

getAllMigrationServices

private Enumeration getAllMigrationServices()
                                     throws WTException
Throws:
WTException

escapeName

private StringBuffer escapeName(String userName)
Given the incoming name, escape it.

Supported API: false


safeClose

private static void safeClose(Statement stmt)
If the Statement is not null, try to close it, catching and smothering any IOException that results.


safeClose

private static void safeClose(ResultSet rs)
If the Statement is not null, try to close it, catching and smothering any IOException that results.