Kyle Brandt

Original computing and productivity articles by a Linux administrator

Archive for April, 2009

Non-Exchange Active Directory Users and the Global Address List

without comments

The Problem
I have some users who are on a different mail system but still part of my company. The problem was that the users without Exchange 2003 accounts were not showing up in the Global Address List (GAL).

Solution
The first step was to look at the LDAP filter that generates the GAL. This can be viewed by going into the ‘Exchange System Manager’ and then ‘Recipients::All Global Address Lists::Default Global Address List::General Tab’. The following is the filter on my Exchange system (which I am guessing is the default ):

(& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=contact))(objectCategory=group)(objectCategory=publicFolder)(objectCategory=msExchDynamicDistributionList) ))


Looking at this filter, and not being rain man, I couldn’t just glance at and figure out what it meant. The trick was to load it with VIM, because it will highlight matching parenthesis (When your cursor is over the opening parenthesis, the match closing parenthesis gets highlighted). I then I indented based on that which resulted in:

(&
   (mailnickname=*)
   (|
      (&
         (objectCategory=person)
         (objectClass=user)
         (!(homeMDB=*))
         (!(msExchHomeServerName=*))
      )
      (&
         (objectCategory=person)
         (objectClass=user)
         (|
            (homeMDB=*)
            (msExchHomeServerName=*))
      )
      (&
         (objectCategory=person)
         (objectClass=contact)
      )
      (objectCategory=group)
      (objectCategory=publicFolder)
      (objectCategory=msExchDynamicDistributionList)
   )
)

The next step was to look at the active directory key value pairs for for one of the users that wasn’t showing up in the GAL. I know of two ways to do this, one is to use adsiedit.msc for windows, or, if you want to be super cool, use ldapsearch in Linux. To use ldapsearch to look at the attributes for the object, you would use a command like: ldapsearch -w $PW -v -x -D "cn=Administrator,cn=Users,dc=myDomain,dc=com" "cn=Kyle Brandt" where ‘Kyle Brandt’ is the user you want to look at, Administrator is the user you use to authenticate with AD, PW is a shell environment variable with you password, and myDomain is your company’s AD domain name.
Once I saw that mailNickname was not set, and since the filter says ’show in GAL if mailNickname is set to something, OR if … lots of stuff …’ all I had to do was use adsiedit to set that attribute to something. To learn how to read and write these filters see this rfc or this msdn page. You can see if the change will effect the GAL book by clicking ‘Preview’ on the tab were the filter originally was. It will probably take a day or so (depending on your settings) before the change is actually made to the GAL.

Written by Kyle

April 10th, 2009 at 7:03 am

My Not-So-Shabby Screen and Gnome-Terminal Setup

with 3 comments

Introduction
For a system administrator it is important to have an efficient and comfortable interface to all your servers. GNU Screen is an excellent utility to be able to have a single terminal connected to multiple servers that won’t disappear when you close the window. I have a set up that allows me to spawn gnome-terminal with different screen sessions for each location I administer in a different tab. Then each screen session has a named ‘tab’ that automatically logs into each server at that location. It ends up looking like this:

Gnome Terminal and Screen

My main two recommendations for screen are to set up the meta character as back-tick ( ` ) and to give screen a ‘tab bar’. You can read how to do these two things here.

Setting up Screen
Once you have screen set up the way you like, you can the specify an additional screenrc file with the -c switch and your settings in the ~/.screenrc will still be used. The secondary screenrc is where you can list different server groups. This file will make it so there are named ‘tabs’ for each server, and each tab will log into the server you specify. Each line in the file should be something like ’screen -t myServer ssh myServer’, the first mySever is the name of the tab, and then ssh myServer is the command that will be run. To simplify doing this in the future, I made a little Perl script that reads a file that has one server name per line and prints the rc file to standard out.

#!/usr/bin/perl
#===============================================================================
#         FILE:  makeScreenRc.pl
#        USAGE:  ./makeScreenRc.pl
#       AUTHOR:  Kyle Brandt (kb), kyle@kbrandt.com
#===============================================================================

use strict;
use warnings;

print "zombie qr\n";
while (<>) {
        chomp;
        my $server = $_;
        print "screen -t $server ssh $server", "\n";
}

So if you called the above script with something like ‘perl makeScreenRc.pl myDmzList > myScreenDmzRc’ you can then use the created file with ’screen -R DMZ -c myScreenDmzRc’. The capital R switch looks for an existing detached session and will attempt to reattach it before creating a new one. This will be useful with gnome-terminal in case gnome-terminal crashes.

Setting Up Gnome-Terminal
The next step is to create a profile for each of the screen sessions. You can do this by going to File::New Profile and then create a profile with a relevant name for the screen session, i.e. ‘DMZ’ . After that, Go to the Title and Command tab, check ‘Run a custom Command instead of my shell’ and and edit the command to be something like ’screen -R DMZ -c myScreenDmzRc’. Then repeat this for each of the screen sessions you have set up. Then, you can run something like ‘gnome-terminal –tab-with-profile=DMZ –tab-with-profile=MyOffice’ where DMZ and MyOffice are the names of the gnome-terminal profiles you created. This automatically detaches itself from the controlling terminal, so if you close the terminal you launched this from, the new terminal will not close. Lastly, you can set up a shell alias to run the above command, so all you have to do to open up your command central is type something like ‘myservers’.

Written by Kyle

April 9th, 2009 at 12:08 pm

A Perl API for TVRage – WebService::TVRage

with 2 comments

The Module
This new module I have written provides an object oriented interface to TVRage’s XML service which allows you to get episode and other information for television shows. It is written very similarly to my previous module, WebService::UPS, and also uses XML::Simple and Mouse. You can get the module from CPAN here. You can also install it with ’sudo cpan -i WebService::TVRage’.

Example:

use WebService::TVRage::EpisodeListRequest;
use WebService::TVRage::ShowSearchRequest;

my $searchReq =   WebService::TVRage::ShowSearchRequest->new();
my $searchResults = $searchReq->search('Heroes');
my $heroFromSearch = $searchResults->getShow('Heroes');
print $heroFromSearch->getLink(), "\n";
print $heroFromSearch->getCountry(), "\n";
print $heroFromSearch->getStatus(), "\n";
my $heroes =  WebService::TVRage::EpisodeListRequest->new( 'episodeID' => $heroFromSearch->getShowID() );
my $episodeList = $heroes->getEpisodeList();
print $episodeList->getNumSeasons(), "\n";
my $episode = $episodeList->getEpisode(1,3);
print $episode->getTitle(), "\n";
print $episode->getAirDate(), "\n";
foreach my $showtitle ($searchResults->getTitleList()) {
   my $show = $searchResults->getShow($showtitle);
   print $show->getLink();
}

Written by Kyle

April 8th, 2009 at 5:38 am

Posted in Perl, Programming

Tagged with ,

A Line By Line Explanation of Selection Sort from Mastering Algorithms with Perl

without comments

Introduction:
O’Reilly’s Mastering Algorithms with Perl is written for programmers who are already quite familiar with Perl. I thought it might help myself and maybe others to walk through the code for selection sort that is on Page 120 because the code isn’t the clearest Perl. My analysis is not meant to explain selection sort because the book does that. Rather, it is to explain the Perl code.

The Code:

#!/usr/bin/perl 

use strict;
use warnings;

sub selection_sort {
    my $array = shift;

    my $i;      # The starting index of a minimum-finding scan.
    my $j;      # The running index of a minimum-finding scan.

    for ( $i = 0; $i < $#$array ; $i++ ) {
        my $m = $i;             # The index of the minimum element.
        my $x = $array->[ $m ]; # The minimum value.

        for ( $j = $i + 1; $j < @$array; $j++ ) {
        ( $m, $x ) = ( $j, $array->[ $j ] ) # Update minimum.
            if $array->[ $j ] < $x;
        }

        # Swap if needed.
        @$array[ $m, $i ] = @$array[ $i, $m ] unless $m == $i;
    }
}

my @array = (1, 7, 2, 8, 2, 5, 20);
selection_sort(\@array);
print "@array\n";

The only change I made to the code from the example is to change lt to < on line 18 so the comparison is numerical and not by ascii value.

Analysis:
Line 27 passes a reference to the @array array to the selection_sort subroutine. This makes it so the array is changed in place and a copy of the array does not have to be made.

Line 7 makes the variable $array , which is local to the function selection_sort, a reference to the array in line 26. ’shift’ removes the first argument to the function from the @_ array. The @_ is the default variable within a subroutine so it can be omitted. The line could have been written as $array = shift(@_); .

Line 12 uses a c-style for loop (Please forgive the messed up syntax highlighting). In Perl for and foreach do the same thing. However, a for or foreach loop is context sensitive depending on what comes after the for/foreach keyword. So Perl programmers use for when they are writing a c-style loop. The c-style loop is used for array indexing here. The first statement, $i = 0; initializes the index variable. The second statement, $i < $#$array; is the exit condition as in a while loop. The third statement $i++ increments by one each loop. In the second statement, $#$array, means ‘the index of the last element of the array that the reference $array points to’. Since it is less than instead of less than or equal to, and it is the last index of the array, not the number of items in the array, the loop will stop before the last element of the array.

Line 14 is again using references, so $array->[ $m ] returns the value of the index $m in array that $array points to.

Line 16, like 12, uses the c-style loop. This time the exit condition (the second statement in the loop header) is $j < @$array . This dereferences the array that $array points to, and evaluates in scalar context which returns the number of items in the array. So this also could have been written as $j <= $#$array .

Line 17 and 18 are like a standard if statement but it is written backwards. This is known as postfix syntax, a trailing conditional, or a statement-modifying if. Note, this is written as one line — there is no semi-colon.

Line 22 also uses the trailing conditional, this time it is ‘unless’. This line uses array slices to swap the items. The slice [ $m, $i ] selects two items, the item at index $m and index $i . It does not select a range like the python array[0:2] . In Perl you use the range operator .. instead of : . And again @$array deferences the array, you will often see this written as @{$array} .

Conclusion
I hope this helps someone else who is reading this book, thanks to everyone in #perl on irc.freenode.com for the help.

Written by Kyle

April 4th, 2009 at 8:32 am

Posted in Perl, Programming

Tagged with