Tuesday, September 09, 2008

Citrix “There are no items to display” when viewing Users

When attempting to view the active users on my Citrix servers I receive the message “There are no items to display”. This is my new Citrix 4.5 farm and this feature works in our old 3.0 farm and is relied upon quite a bit for locating users and such. A bit of googling turned up nothing, other people have seen the problem, but nobody knows the resolution.
A bit of testing and I realized that my test system (which has lots of non-standard stuff on it and configured) does list the active users, so the UI can show active users, but the other systems aren’t working. So what's different on my test box:
· 32 vs. 64 bit – my test system is 32bit, and some of the problem systems are also
· hotfix level – same on all systems
· system used in discovery – executing discovery locally on a problematic server still fails to list active users
· installed components – I updated a system to have all the same components
· license level – I changed the license levels to Enterprise on both, same issue
· zone name – both are in the same zone
· OS version – both are W2k3 SP2
· Connectivity to the data collector – I can successfully telnet to port 2512 on the DC from all systems
No differences appear to be identifying the issue. I contacted our vendor who put me in contact with a Citrix rep and we tried a few more things: various qfarm commands, some cleaning of the datastore, moving a server into its own farm, etc… Nothing seemed to resolve the issue.
Finally we deleted and recreated the ICA listener and the connections started showing, something in the ICA config was broken and since most of these servers were built from an image they all had the same problem. I started researching the differences between the working ICA listeners and the broken ones and noticed that the security was different. On the working listeners, the Local Service and Network Service accounts had Query and Message rights, and the broken listeners didn’t have any rights.
I added the two users with rights to the ICA listener on a broken system and logged off. In the AMC I looked for Sessions and the ICA-Tcp session appears, logged back onto the server and my name appears. A little more research shows that the RDP listener was failing due the same issue, resetting the security on it allows the sessions and users to be displayed

Before:Changes made to both services on both listeners:After change:

Monday, September 08, 2008

Restricting Citrix users on the CSG

I have a need to restrict users who can access the Citrix Web Interface (v 4.6) from outside the company, yet allow everyone to access it from inside. Some searching turned up several references to people restricting access based on username or group membership (such as http://www.jasonconger.com/Controlling-Access-to-Web-Interface-using-Web-Interface-Access-Control-Center.aspx), but nobody looked at how the site was being accessed. My first thought was to setup 2 web interfaces (one internal and one external) and use one of these functions, but I needed other customizations and I didn't like the idea of having to keep them in sync.

A little searching in the out of the box code and I realized there is an existing function called isUsingSecureGateway() that reports if the connection is being proxied via the Citrix Secure Gateway, this is exactly what I needed. Combine this function with examples from others and I have it all.

Step 1: Setup the code

I created a new file named /App_Data/wiCustomizations/CSGRestrict.aspxf to house the interface customizations. This file will contain the functions to check group membership and to search for membership within the group. The key here is to configure the variable groupsPermitted with the names of the security groups to allow access. The groupsPermitted is comma delimited (i.e. add multiple groups with commas in between) and are compared via regular expressions; this means that wildcards can be used to permit users. This file is stored as text on the web server and can easily be edited at any time to add/remove groups.

The second item to notice is the LDAP call needs a username and password to access active directory. Unless you have configured IIS to run under a domain account (not suggested) then you will need to add in a username here. Make sure this account has limited rights since the password will be stored in clear text and anyone with access to the server will have access to the password.

bool CSGAllow(string username, string domain)


string groupsPermitted = "Domain Admins,.*csgaccess";

bool bAllowed = MemberOf(username, domain, groupsPermitted);

return bAllowed;


bool MemberOf(string userName, string domainName, string groupNames)


bool retVal = false;

System.DirectoryServices.DirectoryEntry dirEntry = new System.DirectoryServices.DirectoryEntry("LDAP://" + domainName, "username", "password");

System.DirectoryServices.DirectorySearcher dirSearcher = new System.DirectoryServices.DirectorySearcher(dirEntry);

dirSearcher.Filter = string.Format("(sAMAccountName={0})", userName);


int propCount = 0;

System.DirectoryServices.SearchResult dirSearchResult = dirSearcher.FindOne();

propCount = dirSearchResult.Properties["memberOf"].Count;

for (int i = 0; i < propCount - 1; i++)


string member = dirSearchResult.Properties["memberOf"][i].ToString();

foreach (string strGroup in groupNames.Split(",".ToCharArray()))


System.Text.RegularExpressions.Regex myPattern = new System.Text.RegularExpressions.Regex("cn=" + strGroup + ".*,", System.Text.RegularExpressions.RegexOptions.IgnoreCase);

if (myPattern.IsMatch(member))






Step 2: Link into the login process

Two files need to be edited here – the first is /auth/login.aspx to reference our customized code

<!--#include file="~/app_data/wiCustomizations/serverscripts/csgRestrict.aspxf"-->

The second file to edit is /App_Data/auth/serverscripts/login.aspxf to initiate the security group check. The inserted code is highlighted below.

// Make sure none of the credential fields contain control characters

if( Strings.hasControlChars( user )

|| Strings.hasControlChars( password )

|| Strings.hasControlChars( domain )

|| Strings.hasControlChars( context )

|| Strings.hasControlChars( passcode ) ) {

messageCenterControl.setType( MessageCenterControl.MSGTYPE_ERROR );

messageCenterControl.setKey( "InvalidCredentials" );

} else
if (expAuth is ExplicitNDSAuth) {

// Defer to special NDS processing code that handles context lookup

result = loginAuthenticateNDS((ExplicitNDSAuth) expAuth, user, password, passcode, context);


if (isUsingSecureGateway() && !CSGAllow(user, domain))







// Not NDS - parse the fields and go do any Two-factor

ExplicitUDPAuth udpAuth = (ExplicitUDPAuth)expAuth;

Step 3: Define a custom error message

The final step is to setup a custom error message alerting users they don't have access via the CSG. Using the Citrix article http://support.citrix.com/article/CTX107490 as guidance I copied the common_strings.properties file to the languages folder in the web interface. I then edited the file and added the below line, ensuring the variable NoCSGAccess matches the string that is called from login.aspxf above.

NoCSGAccess=This account has not been approved for accessing the Web Interface via the CSG

Wednesday, September 03, 2008

Configuring Citrix on Ubuntu

Installing the Citrix client is easy, just download and execute it

Opening a connection however fails with the error
You have not chosen to trust "/C=US/ST=/L=/O=Equifax Secure Certificate Authority/CN=", the issuer of the server's security certificate

To fix this, we need to download the Root CA certs
Download all Equifax certificates and rename them from .CER to .CRT and then as root copy them to /usr/lib/ICAClient/keystore/cacerts

Viola! The published apps now open