2 ################################################################################
5 # Description: This script enables LDAP Authentication on a DB set. LDAP
6 # Authentication is supported in Clearquest 2003.06.15 and higher.
8 # Author: Andrew@DeFaria.com
9 # Created: Fri Sep 23 17:27:58 PDT 2005
11 # Modules: Term::ReadLine, Term::ReadKey
13 # (c) Copyright 2005, Andrew@DeFaria.com, all rights reserved
15 ################################################################################
21 $0 =~ /(.*)[\/\\](.*)/;
22 my $me = (!defined $2) ? $0 : $2;
30 print "ERROR: $msg\n" if defined $msg;
32 print "Usage: $me [-n] [-v] [-u]
36 -n: No execute mode (Default Execute)
37 -v: Turn on verbose mode (Default off)
38 -f: Configuration file (Default ldap_settings.cfg)
39 -u: Display this usage
48 print "$msg" if $verbose;
55 if (!defined $errno) {
56 $msg = "$me: ERROR: $msg";
58 $msg = "$me: ERROR: #$errno: $msg"
63 exit $errno if defined $errno;
66 sub DisplayLDAPParms {
69 print "\nLDAP Parms:\n";
71 foreach (sort (keys (%ldap_parms))) {
73 print "$_: <password>\n";
75 print "$_: ${ldap_parms {$_}}\n";
81 my $config_file = shift;
85 open SETTINGS, $config_file
86 or error "Unable to open $config_file ($!)", 1;
91 next if /^$/; # Skip blank lines
92 next if /^\#/; # and comments
94 if (/^dbset:\s*(.*)/i) {
95 $ldap_parms{dbset} = $1;
96 } elsif (/^admin_username:\s*(.*)/i) {
97 $ldap_parms{admin_username} = $1;
98 } elsif (/^admin_password:\s*(.*)/i) {
99 $ldap_parms{admin_password} = $1;
100 } elsif (/^servers:\s*(.*)/i) {
101 $ldap_parms{servers} = $1;
102 } elsif (/^port:\s*(.*)/i) {
103 $ldap_parms{port} = $1;
104 } elsif (/^port:\s*(.*)/i) {
105 $ldap_parms{port} = $1;
106 } elsif (/^search_distinguished_name:\s*(.*)/i) {
107 $ldap_parms{search_distinguished_name} = $1;
108 } elsif (/^search_password:\s*(.*)/i) {
109 $ldap_parms{search_password} = $1;
110 } elsif (/^basedn:\s*(.*)/i) {
111 $ldap_parms{basedn} = $1;
112 } elsif (/^scope:\s*(.*)/i) {
113 $ldap_parms{scope} = $1;
114 } elsif (/^account_attribute:\s*(.*)/i) {
115 $ldap_parms{account_attribute} = $1;
116 } elsif (/^search_filter:\s*(.*)/i) {
117 $ldap_parms{search_filter} = $1;
118 } elsif (/^cq_field:\s*(.*)/i) {
119 $ldap_parms{cq_field} = $1;
120 } elsif (/^attribute_search_entry:\s*(.*)/i) {
121 $ldap_parms{attribute_search_entry} = $1;
122 } elsif (/^test_username:\s*(.*)/i) {
123 $ldap_parms{test_username} = $1;
133 my $prefix = shift; # Prefix or question being asked
134 my $default = shift; # default value - if any
135 my $suffix = shift; # Suffix (default ":")
136 my $password = shift; # Whether or not to turn off echo (default "no");
138 $default = "" if !defined $default;
139 $suffix = ":" if !defined $suffix;
140 $password = "no" if !defined $password;
146 print " [$default]" if $default ne "" and $password ne "yes";
149 if ($password eq "yes") {
151 $value = ReadLine (0);
158 $value = $default if $value eq "";
159 } until $value ne "";
165 my $config_file = shift;
168 open SETTINGS, ">$config_file"
169 or error "Unable to open $config_file ($!)", 2;
171 foreach (sort (keys (%ldap_parms))) {
172 if ($_ eq "cq_field") {
174 $value = "CQ_EMAIL" if $ldap_parms {$_} eq "1";
175 $value = "CQ_FULLNAME" if $ldap_parms {$_} eq "2";
176 $value = "CQ_LOGIN_NAME" if $ldap_parms {$_} eq "3";
177 $value = "CQ_MISC_INFO" if $ldap_parms {$_} eq "4";
178 $value = "CQ_PHONE" if $ldap_parms {$_} eq "5";
179 print SETTINGS "$_:\t$value\n" if $value ne "";
181 print SETTINGS "$_:\t${ldap_parms {$_}}\n";
191 print "DBSET name: This is the name of the Clearquest database set - also
192 known as database connection name. This can be found in the Clearquest
193 Maintainance Tool. Often this is something like \"2003.06.15\".
196 $ldap_parms {dbset} = Prompt "What is the DBSET name that you wish to enable LDAP on", $ldap_parms {dbset};
199 Now we need to know the username and password of the administrative
200 user for the $ldap_parms{dbset} DBSET:
203 $ldap_parms {admin_username} = Prompt "Admin username", $ldap_parms {admin_username};
204 $ldap_parms {admin_password} = Prompt "${ldap_parms {admin_username}}'s password", $ldap_parms {admin_password}, undef, "yes";
207 print "\nA: LDAP Server\n";
209 Now we need to know the name of the LDAP server to authenticate to.
211 What is the host name of the LDAP server? You can specify multiple
212 hosts so that ClearQuest can attempt to connect to an alternate host
213 if it cannot connect to the first one.
215 You can specify multiple servers separated by commas.
218 $ldap_parms {servers} = Prompt "LDAP Server(s)", $ldap_parms {servers};
221 print "\nB: LDAP Port\n";
223 What is the TCP port number (non-SSL) where the LDAP server listens
227 $ldap_parms {port} = Prompt "LDAP port", $ldap_parms {port};
229 # C: LDAP Search Username/Password
230 print "\nC: LDAP Distinguished Name for Search Account/Password\n";
231 print "\nDoes the LDAP server allow anonymous searches (Y/n)? ";
234 if ($_ !~ /^y|^yes|^$/i) {
235 # C1: LDAP Search username
237 What is the distinguished name (DN) of the search account?
239 For example: cn=search_user,cn=Users, dc=cqldapmsft,dc=com
242 $ldap_parms {search_distinguished_name} = Prompt "ClearQuest users. LDAP Search user name", $ldap_parms {search_distinguished_name};
244 # C2: LDAP Search passwrod
245 $ldap_parms {search_password} = Prompt "Password", $ldap_parms {search_password}, undef, "yes";
249 print "\nD: LDAP BaseDN\n";
251 Now here's where things get tricky. LDAP uses a BaseDN or Base
252 Distinguished Name as a sort of path into the LDAP directory. Your
253 LDAP Administrator should be able to provide you with this
256 What is the base DN from which to start searching for LDAP user
257 directory entries that correspond to ClearQuest users? The base DN
258 must be high enough in the directory hierarchy to include all users
259 that might need to be authenticated; however, a base DN that is too
260 high in the hierarchy might slow login performance.
263 $ldap_parms {basedn} = Prompt "LDAP BaseDN", $ldap_parms {basedn};
266 while (!defined $ldap_parms {scope} or
267 ($ldap_parms {scope} ne "sub" and
268 $ldap_parms {scope} ne "one" and
269 $ldap_parms {scope} ne "base")) {
270 print "\nE: LDAP Scope\n";
272 What is the scope of the search from the base DN?: sub (subtree); one
273 (one level below); or base (base DN only).
276 $ldap_parms {scope} = Prompt "LDAP Scope [sub|one|base]", $ldap_parms {scope};
279 # F: LDAP Account Attribute
280 print "\nF: LDAP Account Attribute\n";
282 What is the LDAP attribute that is used to store the user entry login
283 name values? ClearQuest uses the text string entered in the ClearQuest
284 Login window to search the LDAP directory for a user entry whose LDAP
285 attribute value matches the login name. This LDAP attribute must store
286 unique values for all user entries that ClearQuest searches. You also
287 use this attribute in the answer to the next question.
289 For example: samAccountName
292 $ldap_parms {account_attribute} = Prompt "LDAP Account Attribute", $ldap_parms {account_attribute};
294 # G: LDAP Search Filter
295 print "\nG: LDAP Search Filter\n";
297 What is the LDAP search filter that ClearQuest must use to select the
298 LDAP user entry based on the attribute specified in the previous
299 question? Use \%login\% as the user's login name; ClearQuest substitutes
300 the text string the user enters in the ClearQuest login window.
302 For example: ${ldap_parms {account_attribute}}=\%login\%
305 $ldap_parms {search_filter} = Prompt "LDAP Search Filter", $ldap_parms {search_filter};
307 # H: LDAP Attribute Search Entry
308 print "\nH: LDAP Attribute Search Entry\n";
310 What is the LDAP attribute of the user entry to be used to map the
311 user to a corresponding ClearQuest user profile record? You can map an
312 attribute to one of the following ClearQuest user profile record
313 fields: CQ_EMAIL, CQ_FULLNAME, CQ_LOGIN_NAME, CQ_MISC_INFO, or
314 CQ_PHONE. The ClearQuest administrator and LDAP administrator need to
315 work together to determine this mapping.
317 First specify the Clearquest field you wish to map to:
326 my $default_cq_field;
328 if ($ldap_parms {cq_field} eq "CQ_EMAIL") {
329 $default_cq_field = 1;
330 } elsif ($ldap_parms {cq_field} eq "CQ_FULLNAME") {
331 $default_cq_field = 2;
332 } elsif ($ldap_parms {cq_field} eq "CQ_LOGIN_NAME") {
333 $default_cq_field = 3;
334 } elsif ($ldap_parms {cq_field} eq "CQ_MISC_INFO") {
335 $default_cq_field = 4;
336 } elsif ($ldap_parms {cq_field} eq "CQ_PHONE") {
337 $default_cq_field = 5;
339 $default_cq_field = 0;
343 $ldap_parms {cq_field} = Prompt "Enter choice (1-5)", $default_cq_field;
344 } until ($ldap_parms {cq_field} > 0 and $ldap_parms {cq_field} < 6);
346 print "\nH: LDAP Attribute Search Entry\n";
348 Now enter the corresponding LDAP field that this maps to.
351 $ldap_parms {attribute_search_entry} = Prompt "LDAP Attribute Search Entry", $ldap_parms {attribute_search_entry};
353 # I: LDAP Test Username
354 print "\nI: LDAP Test Username\n";
356 What is the login name of a user entry that can be used to validate
357 that ClearQuest can correctly authenticate a user against the LDAP
358 directory? This can be a test account or an actual user account.
361 $ldap_parms {test_username} = Prompt "LDAP Test Username", $ldap_parms {test_username};
363 # J: LDAP Test Password
364 print "\nJ: LDAP Test Password\n";
366 What is the password for the user entry specified in the previous
370 $ldap_parms {test_password} = Prompt "LDAP Test Password", $ldap_parms {test_password}, undef, "yes";
375 sub SetAuthentication2CQOnly {
378 my $cmd = "installutil setauthenticationalgorithm " .
379 $ldap_parms {dbset} . " " .
380 $ldap_parms {admin_username} . " " .
381 $ldap_parms {admin_password} . " " .
391 print "Error executing $cmd\n";
399 } # SetAuthentication2CQOnly
404 my $cmd = "installutil setldapinit " .
405 $ldap_parms {dbset} . " " .
406 $ldap_parms {admin_username} . " " .
407 $ldap_parms {admin_password} . " \"" .
408 "-h " . $ldap_parms {servers} . " " .
409 "-p " . $ldap_parms {port};
411 if (defined $ldap_parms {search_distinguished_name}) {
412 $cmd .= " -D " . $ldap_parms {search_distinguished_name} .
413 " -w " . $ldap_parms {search_password};
425 print "Error executing $cmd\n";
438 my $cmd = "installutil setldapsearch " .
439 $ldap_parms {dbset} . " " .
440 $ldap_parms {admin_username} . " " .
441 $ldap_parms {admin_password} . " \"" .
442 "-s " . $ldap_parms {scope} . " " .
443 "-b " . $ldap_parms {basedn} . " " .
444 $ldap_parms {search_filter} . "\"";
452 print "Error executing $cmd\n";
473 my $cq_field = $cq_fields [($ldap_parms {cq_field} - 1)];
475 my $cmd = "installutil setcqldapmap " .
476 $ldap_parms {dbset} . " " .
477 $ldap_parms {admin_username} . " " .
478 $ldap_parms {admin_password} . " " .
480 $ldap_parms {attribute_search_entry};
489 print "Error executing $cmd\n";
499 sub ValidateLDAPConfig {
502 my $cmd = "installutil validateldap " .
503 $ldap_parms {dbset} . " " .
504 $ldap_parms {admin_username} . " " .
505 $ldap_parms {admin_password} . " " .
506 $ldap_parms {test_username} . " " .
507 $ldap_parms {test_password};
516 print "Error executing $cmd\n";
525 } # ValidateLDAPConfig
527 sub SetAuthentication2CQFirst {
529 my $cmd = "installutil setauthenticationalgorithm " .
530 $ldap_parms {dbset} . " " .
531 $ldap_parms {admin_username} . " " .
532 $ldap_parms {admin_password} . " " .
542 print "Error executing $cmd\n";
550 } # SetAuthentication2CQFirst
552 my $config_file = "ldap_settings.cfg";
555 if ($ARGV [0] eq "-v") {
557 } elsif ($ARGV [0] eq "-n") {
559 } elsif ($ARGV [0] eq "-u") {
561 } elsif ($ARGV [0] eq "-f") {
563 if ($ARGV [0] eq "") {
564 Usage "Must specify config file after -f";
566 $config_file = $ARGV [0];
568 Usage "Unknown argument found: " . $ARGV [0];
574 my %ldap_parms = ParseSettings $config_file;
576 print "$me: Enable Clearquest LDAP Authentication on a dbset
578 First we need to ask some questions...
582 %ldap_parms = GetLDAPParms %ldap_parms;
584 DisplayLDAPParms %ldap_parms;
586 print "Proceed (Y/n)? ";
589 if ($_ =~ /^y|^yes/i) {
590 print "OK, quitting...\n";
594 if (-f $config_file) {
595 print "Save settings overwriting $config_file (y/N)? ";
598 if ($_ =~ /^y|^yes/i) {
599 SaveSettings $config_file, %ldap_parms;
602 SaveSettings $config_file, %ldap_parms;
605 SetAuthentication2CQOnly %ldap_parms;
606 SetLDAPInit %ldap_parms;
607 SetLDAPSearch %ldap_parms;
608 MapLDAPFields %ldap_parms;
609 ValidateLDAPConfig %ldap_parms;
610 SetAuthentication2CQFirst %ldap_parms;