This utility provides a mechanism to view LDAP (RDS) group membership.
With Rational Directory Server, the user and group lists often get truncated and it is almost impossible to inspect group membership from within DOORS.
DOORS will only “download” the users and groups that it needs for the current session, so when you open a module and look at the properties, doors downloads just the users and groups that apply to that item.
This tool forces the users and groups to be read by doors and then stores them for access later.
Group members are cached using configuration files and can be updated on demand.
This can take a few minutes to run, but once you have done that then the user/group membership is readily available for you to browse.
I do not know why, but during testing this returned different results for different users.
// View LDAP Group Membership /* Provides a mechanism to view LDAP (RDS) group membership. With Rational Directory Server, the user and gtroup lists often get truncated and it is almost impossible to inspect group membership from within DOORS. DOORS will only "download" the users and groups that it needs for the current session, so when you open a module and look at the properties, doors downloads just the users andd groups that apply to that item. This tool forces the users and groups to be read by doors and then stores them for access later. Group members are cached using configuration files and can be updated on demand. This can take a long time to run, but once you have done that then the user/group membership is readily available. I do not know why, but during testing this returned different results for different users. 07-AUG-2012 Tony Goodman */ pragma runLim, 0 #include <SmartDXL/smartDialogs.inc> // Use these to reduce the seacrhing required for users and groups. // For example, if you know that your usernames are made up of numbers only, // then just have numbers in the USER_CHARS variable. // The following also assumes that all groups used by DOORS begin with "DOORS" // Note that user and group names are not case sensitive in RDS or LDAP, so you don't need to include // uppercase letters. string USER_PREFIX = "" string GROUP_PREFIX = "DOORS" string USER_CHARS = "0123456789" string GROUP_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_ " DB dbMain = null DBE dbeGroups = null DBE dbeMembers = null DBE dbeSplitter = null DBE dbeReload = null DBE dbeLastUpdated = null string CONF_DIR = "ldap_groups" string LAST_UPDATED = "last_updated" string dummy[] = {} /****************************************************************************** recordDate ******************************************************************************/ void recordDate() { ConfStream conf = null conf = confWrite(CONF_DIR "\\" LAST_UPDATED , confUser) if (!null conf) { conf << stringOf(dateAndTime(today)) "\n" close(conf) } } /****************************************************************************** recordMembers ******************************************************************************/ void recordMembers(Group g) { ConfStream conf = null User u = null string groupName = "" string userName = "" Skip skipUsers = createString if (!confFileExists(CONF_DIR, confUser)) { // add directory confMkdir(CONF_DIR, confUser) } groupName = g.name conf = confWrite(CONF_DIR "\\" groupName, confUser) if (!null conf) { for u in g do { userName = u.name put(skipUsers, userName, userName) } for userName in skipUsers do { conf << userName "\n" } close(conf) } } /********************************* Returns true if the count is suspicious **********************************/ bool truncated(int count) { return(count == 499 || count == 500 || count == 999 || count == 1000) } /**************************************************************** Load all LDAP groups beginning with the supplied prefix to the DOORS client. Call with empty string parameter for a complete list... and a long wait. *****************************************************************/ void loadLdapGroups(string prefix) { Group g = null int i = 0 int count = 0 for g in groupList(prefix "*") do { count++ } print(count " groups beginning with " prefix "\n") if (truncated(count)) { for (i = 0; i < length(GROUP_CHARS); i++) { loadLdapGroups(prefix GROUP_CHARS[i:i]) } } } /******************************************************************** Load all LDAP users beginning with a digit to the DOORS client. Call with empty string parameter for the complete list of users with a numeric id. *********************************************************************/ void loadLdapUsers(string prefix) { User u = null int i = 0 int count = 0 for (i = 0; i < length(USER_CHARS); i++) { count = 0 for u in userList(prefix USER_CHARS[i:i] "*") do { count++ } print(count " users beginning with " prefix USER_CHARS[i:i] "\n") if (truncated(count)) { loadLdapUsers(prefix USER_CHARS[i:i]) } } } /****************************** loadLdapUsersAndGroups *******************************/ void loadLdapUsersAndGroups() { Group g = null loadLdapUsers(USER_PREFIX) loadLdapGroups(GROUP_PREFIX) for g in groupList do { recordMembers(g) } recordDate() } /*********************** initGroupNames ***********************/ void initGroupNames() { ConfStream conf = null string s = "" string lastUpdated = "" for s in confDirectory(CONF_DIR, confUser) do { if (s == "." || s == "..") continue if (s == LAST_UPDATED) continue insert(dbeGroups, noElems(dbeGroups), s, iconGroup) } if (confFileExists(CONF_DIR "\\" LAST_UPDATED, confUser)) { conf = confRead(CONF_DIR "\\" LAST_UPDATED, confUser) if (!null conf) { conf >> lastUpdated close(conf) } set(dbeLastUpdated, "Last updated: " lastUpdated) } } /*********************** doSelect ***********************/ void (DBE dbe, int i) { ConfStream conf = null User u = null string userName = "" string userEmail = "" string groupName = "" int userCount = 0 groupName = get(dbeGroups) empty(dbeMembers) conf = confRead(CONF_DIR "\\" groupName, confUser) if (!null conf) { while (true) { conf >> userName if (end conf) break u = find(userName) if (!null u) { userEmail = u.email insert(dbeMembers, userCount, "", iconUser) set(dbeMembers, userCount, 0, userName) set(dbeMembers, userCount, 1, userEmail) userCount++ } } close(conf) } } /*********************** doSelect ***********************/ void doSelect(DBE dbe, int i) { ConfStream conf = null User u = null string userName = "" string userEmail = "" string groupName = "" int userCount = 0 groupName = get(dbeGroups) empty(dbeMembers) conf = confRead(CONF_DIR "\\" groupName, confUser) if (!null conf) { while (true) { conf >> userName if (end conf) break u = find(userName) if (!null u) { userEmail = u.email insert(dbeMembers, userCount, "", iconUser) set(dbeMembers, userCount, 0, userName) set(dbeMembers, userCount, 1, userEmail) userCount++ } } close(conf) } } /*********************** doActivate ***********************/ void doActivate(DBE dbe, int i) { doSelect(dbe, i) } /*********************** doDeselect ***********************/ void doDeselect(DBE dbe, int i) { ; } /*********************** doReload ***********************/ void doReload(DB db) { if (!confirm("Reloading users and groups from LDAP will take several minutes.\n" //- "Are you sure you want to continue?")) { return } loadLdapUsersAndGroups() initGroupNames() } /*********************** createDialog ***********************/ void createDialog() { dbMain = smartDialog(dbExplorer, "LDAP Group Membership Viewer") dbeGroups = listView(dbMain, 0, 315, 20, dummy) dbeGroups->"right"->"unattached" dbeGroups->"bottom"->"unattached" dbeGroups->"left"->"form" dbeMembers = listView(dbMain, 0, 315, 20, dummy) dbeMembers->"left"->"unattached" dbeMembers->"top"->"aligned"->dbeGroups dbeMembers->"bottom"->"unattached" dbeMembers->"right"->"form" dbeSplitter = splitter(dbMain, dbeGroups, dbeMembers, 5) dbeSplitter->"top"->"aligned"->dbeGroups dbeSplitter->"bottom"->"unattached" dbeSplitter->"left"->"unattached" dbeSplitter->"right"->"unattached" dbeLastUpdated = label(dbMain, "Last updated: ") dbeLastUpdated->"top"->"flush"->dbeGroups dbeLastUpdated->"left"->"form" dbeLastUpdated->"right"->"unattached" dbeLastUpdated->"bottom"->"form" dbeReload = apply(dbMain, "Reload from LDAP", doReload) realize(dbMain) set(dbeGroups, doSelect, doDeselect, doActivate) insertColumn(dbeGroups, 0, "Group Name", 290, iconNone) initGroupNames() insertColumn(dbeMembers, 0, "User Name", 100, iconNone) insertColumn(dbeMembers, 1, "Email Address", 200, iconNone) show(dbMain) } /*********************** MAIN ***********************/ createDialog()