Skip to content

TechBlog

It's about tech

As I’m moving to West Virginia this week it became a priority to get a new cell phone. My current service through Cricket is as spotty as the price is cheap, and there’s a 3-second delay on the line that often results in accidental interruptions. To rationalize further, Cricket’s service in my new city is really, really bad – after 45 minutes on hold with Expedia (during a major snowstorm event on the east coast), the representative said there was too much static on the line and hung up on me.

Sony Ericcson W518

Sony Ericcson W518

My first foray into the expensive world of mainstream cell phones and service plans started out with the Sony Ericcson W518, which was great except for the terribly low earpiece volume (and the wacko proprietary accessory ports…phone-specific headsets are so out of style). After researching AT&T phone options online I went to the local AT&T store and exchanged the W518 for an LG CF360, which has a much more acceptable speaker volume (and more industry-standard ports).

LG CF360

LG CF360

Since I’m moving to West Virginia I’m trying to sublet my apartment and thought it’d be a great idea to take pictures of the place with my first camera phone. Discounting my bad photography skills, the photos came out okay even with the CF360’s low-quality camera. Now to just transfer them to my PC…oops. Without the extra $20 text messaging or data plan on my AT&T account I couldn’t just text the pictures to myself, and all of my Google search results assumed I already had a USB A to USB 5-pin connector cable in hand…which wasn’t in my box o’ cables. Whatever could I do?

The CF360 has Bluetooth capability and I have a USB Bluetooth adapter dongle. After extensive searching I found this post with a photo of an attractive blonde that describes how to send a file to the LG Vu via Bluetooth. I followed the instructions and ka-BAM! File sent (droid.mp3 :D )! But now how to send pictures from the CF360 to my PC over Bluetooth?

Through analytical thinking (and blindly clicking until I hit the right menu) I found a way:

  1. On your PC, click the Bluetooth icon in your system tray
  2. Select the ‘Receive a file’ option
  3. On your LG CF360’s home screen, go to Options > Bluetooth > Search New Device. When your PC’s Bluetooth adapter shows up, pair it with your phone
  4. Locate the file you wish to send to your PC. Select the file and go to Options > Send > Via Bluetooth and select your PC’s Bluetooth adapter
  5. Your PC will prompt you to save the file

Note: I’m on Windows 7. You may have a different experience on other operating systems.

It took a long time to find this procedure and it’s annoying that the available CF360 support makes no mention of it. Indeed, every source except the one mentioned in this post indicated that the USB cable is mandatory if you want to transfer files from your CF360 to your PC or vice versa. The Bluetooth support is noted as nothing more than a mechanism for connecting a hands-free headset.

A bit of code that’s been in production for almost a year now came into question recently and I had an opportunity to examine more closely. It was very simple code to get the GMT time and use it to generate an authorization code. The problem was that the GMT time generated on the server and the GMT time generated on the client did not match.

Yes, I too was baffled. How could this make sense? Time calculated for a specific time zone should be the same when calculated simultaneously from two points, regardless of where those points may be. For a moment I thought I’d discovered a rent in the very fabric of time, which might possibly lead to spectacular adventures in history-hopping (and maybe even next year’s stock market status – I could make billions! [but who needs them when you can buy food and eat it, then go back in time so you never bought it?]).

It turns out not all GMT is created equal, at least according to Java’s java.util.Calendar object. A seemingly-simple method for creating a Calendar with the GMT time zone in fact results in the current time zone being used instead!

Calendar calendar = Calendar.getInstance();
// We want only the current year, month, day, and hour;
// Use GMT so it's standard across all time zones
calendar.set(Calendar.ZONE_OFFSET, 0);
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));

Using this code while your computer’s clock is set to CST will result in a CST Calendar being generated! Instead the following snippet can be used to get an actual GMT Calendar object:

Calendar calendar = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));

It seems that passing the expected time zone in as a constructor argument is much more accurate than using the setter methods after the object has already been created.

I’ve spent a bit less than a week attempting to configure Apache to work with Active Directory authentication for Trac on Windows 2003 Server.  Getting the LDAP syntax correct was an absolute horror and took three times forever. Here I’ve documented my findings.

Final {Apache root}/conf/httpd.conf configuration excerpt:

  <Directory /projects/>
  #Trac setup for mod_python
  SetHandler mod_python
  PythonInterpreter main_interpreter
  PythonHandler trac.web.modpython_frontend
  PythonOption TracEnv C:/Trac/projects/
  PythonOption TracUriRoot /projects

  #Apache authentication setup
  Order allow,deny
  Allow from all
  AuthType Basic
  AuthName "Trac"
  AuthBasicProvider ldap
  AuthLDAPBindDN "anActiveDirectoryUsername@yourdomainname.com"
  AuthLDAPBindPassword passwordForAboveUser
  AuthzLDAPAuthoritative Off

  AuthLDAPURL "ldap://adservernamehere:3268/DC=domainname,DC=com?sAMAccountName?sub"

  require group CN=authorizedGroupNameGoesHere
  </Directory>

Notes:

1. The AuthName directive specifies the text that displays on the login dialog in the form “The server at AuthName requires a username and password”

2. The AuthBasicProvider directive determines which Apache module to load. Using “ldap” as shown here requires that the following LoadModule statements be in your httpd.conf:

LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule ldap_module modules/mod_ldap.so

3. The AuthLDAPBindDN directive refers to a user account that has read access to the Active Directory tree structure. This account is used by Apache to determine whether the user logging in is valid.

4. The AuthzLDAPAuthoritative directive essentially tells Apache to pass information about the authentication to other Apache modules when set to “On”

5. The Require directive determines which users are considered authorized. The syntax shown here tells Apache to only authorize users who are in the group called “authorizedGroupNameGoesHere”.  There are several options for this directive that range from hardcoding authorized usernames to specifying complicated LDAP queries. You can find out more by reading the mod_authnz_ldap documentation.

6. The biggest problem I had was getting the AuthzLDAPURL syntax right. This directive tells Apache how to contact Active Directory and where to look in the tree structure for users. Tip: If you use port 3268 as shown here instead of port 389, your query will be executed against a “flattened” tree structure and therefore is more likely to work – it’s a pisser to get the syntax correct otherwise. Further note that “referrals” or “referral chasing” (I don’t know much about Active Directory, obviously) in your AD tree structure WILL cause problems with the AuthzLDAPURL directive – and there’s no way to turn it off (see Apache Bug 42557). Apparently Apache attempts to reconnect to Active Directory for each referral, but doesn’t reauthenticate using the credentials from the original authentication. My solution was to use a query that excluded tree nodes that were referrals – not intentionally, it just worked out that way.

You will also want to be careful with how specific you are with the AuthzLDAPURL query. In my case

DC=domainname,DC=com

was as specific as I could get before running into referral problems. It was much easier to compose the query after downloading Softerra LDAP Administrator because it showed me in real-time which query arguments caused problems. It includes an option to turn off referral chasing, which was also useful to determine which nodes contained referrals and should therefore be excluded.

Errors

The following errors in {Apache root}/logs/error.log will occur when the account specified by AuthLDAPBindDN does not have permission to read the Active Directory tree structure (most likely the password specified by AuthLDAPBindPassword is wrong or you need to use the Active Directory Distinguished Name for the user):

auth_ldap authenticate: user spork authentication failed; URI /projects/ [LDAP: ldap_simple_bind_s() failed][Invalid Credentials]
user spork: authentication failure for "/projects/": Password Mismatch

The obvious solution is to check the credentials and try again.

The following errors in the error log will occur when the AuthzLDAPURL query is too restrictive to find the user who tried to log in:

auth_ldap authenticate: user spork authentication failed; URI /projects/ [User not found][No Such Object]
auth_ldap authenticate: user spork authentication failed; URI /projects/FieldPlus [ldap_search_ext_s() for user failed][No Such Object]

The solution I found was to change the AuthzLDAPURL query to least restrictive and work towards more specific until it found my user account (using Softerra LDAP Administrator).

The following error in the error log will occur when the AuthzLDAPURL query results in referral chasing:

auth_ldap authenticate: user spork authentication failed; URI /projects/FieldPlus [ldap_search_ext_s() for user failed][Operations Error]

The solution I found was to again change the AuthzLDAPURL query until no more referrals were included.