]> andersk Git - gssapi-openssh.git/blame - setup/setup-openssh.pl
o Formatting changes to standard output of setup script.
[gssapi-openssh.git] / setup / setup-openssh.pl
CommitLineData
7a7884ad 1#!/usr/bin/perl
20d3226a 2#
5002372c 3# setup-openssh.pl
4#
95f536ac 5# Adapts the installed gsi-openssh environment to the current machine,
5002372c 6# performing actions that originally occurred during the package's
7# 'make install' phase.
701aa556 8#
1eab725d 9# Send comments/fixes/suggestions to:
10# Chase Phillips <cphillip@ncsa.uiuc.edu>
701aa556 11#
20d3226a 12
7e12c9a7 13#
14# Get user's GPT_LOCATION since we may be installing this using a new(er)
15# version of GPT.
16#
17
18$gptpath = $ENV{GPT_LOCATION};
19
20#
21# And the old standby..
22#
23
4f276ad7 24$gpath = $ENV{GLOBUS_LOCATION};
ad71c979 25if (!defined($gpath))
26{
53a54c67 27 die "GLOBUS_LOCATION needs to be set before running this script"
ad71c979 28}
29
7a7884ad 30#
31# Include standard modules
32#
33
34use Getopt::Long;
35use Cwd;
36use Cwd 'abs_path';
37
8b73e3d0 38#
39# modify the ld library path for when we call ssh executables
40#
41
42$oldldpath = $ENV{LD_LIBRARY_PATH};
43$newldpath = "$gpath/lib";
44if (length($oldldpath) > 0)
45{
46 $newldpath .= ":$oldldpath";
47}
48$ENV{LD_LIBRARY_PATH} = "$newldpath";
49
ad71c979 50#
51# i'm including this because other perl scripts in the gpt setup directories
52# do so
53#
54
7e12c9a7 55if (defined($gptpath))
56{
57 @INC = (@INC, "$gptpath/lib/perl", "$gpath/lib/perl");
58}
59else
60{
61 @INC = (@INC, "$gpath/lib/perl");
62}
ad71c979 63
4f276ad7 64require Grid::GPT::Setup;
65
7a7884ad 66#
67# script-centred variable initialization
68#
69
ad71c979 70my $globusdir = $gpath;
ad71c979 71my $myname = "setup-openssh.pl";
72
20d3226a 73#
74# Set up path prefixes for use in the path translations
75#
76
d0a1bda7 77$prefix = ${globusdir};
78$exec_prefix = "${prefix}";
79$bindir = "${exec_prefix}/bin";
9cc10d0e 80$sbindir = "${exec_prefix}/sbin";
95f536ac 81$sysconfdir = "$prefix/etc/ssh";
82$localsshdir = "/etc/ssh";
20bb6dc8 83$setupdir = "$prefix/setup/gsi_openssh_setup";
e9ec5455 84
7a7884ad 85#
86# standard key types and their root file name mappings
87#
88
95f536ac 89my $keyfiles = {
90 "dsa" => "ssh_host_dsa_key",
91 "rsa" => "ssh_host_rsa_key",
92 "rsa1" => "ssh_host_key",
93 };
823981ba 94
7a7884ad 95#
96# argument specification. we offload some processing work from later functions
97# to verify correct args by using anon subs in various places.
98#
99
100my($interactive, $force, $verbose);
101
102GetOptions(
103 'interactive!' => \$interactive,
104 'force' => \$force,
105 'verbose' => \$verbose,
106 ) or pod2usage(2);
107
108#
109# main execution. This should find its way into a subroutine at some future
110# point.
111#
112
4f3224f2 113print "$myname: Configuring package 'gsi_openssh'...\n";
114print "---------------------------------------------------------------------\n";
70d921fc 115print "Hi, I'm the setup script for the gsi_openssh package! I will create\n";
116print "a number of configuration files based on your local system setup. I\n";
117print "will also attempt to copy or create a number of SSH key pairs for\n";
b48c75c0 118print "this machine. (Loosely, if I find a pair of host keys in /etc/ssh,\n";
119print "I will copy them into \$GLOBUS_LOCATION/etc/ssh. Otherwise, I will\n";
120print "generate them for you.)\n";
4f3224f2 121print "\n";
b48c75c0 122print " Jacobim Mugatu says,\n";
123print " \t\"Utopian Prime Minister Bad! GSI-OpenSSH Good!\"\n";
4f3224f2 124print "\n";
125
70d921fc 126if ( isForced() )
127{
128 print "WARNING:\n";
129 print "\n";
130 print " Using the '-force' flag will cause all gsi_openssh_setup files to\n";
131 print " be removed and replaced by new versions! Backup any critical\n";
132 print " SSH configuration files before you choose to continue!\n";
133 print "\n";
134}
135
4f3224f2 136$response = query_boolean("Do you wish to continue with the setup package?","y");
137if ($response eq "n")
138{
139 print "\n";
140 print "Exiting gsi_openssh setup.\n";
141
142 exit 0;
143}
144
145print "\n";
146
147makeConfDir();
614e6d8b 148copyPRNGFile();
4f3224f2 149$keyhash = determineKeys();
150runKeyGen($keyhash->{gen});
151copyKeyFiles($keyhash->{copy});
4f3224f2 152copyConfigFiles();
4f3224f2 153
154my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup");
155
156$metadata->finish();
157
158print "\n";
159print "Additional Notes:\n";
160print "\n";
161print " o I see that you have your GLOBUS_LOCATION environmental variable\n";
162print " set to:\n";
163print "\n";
164print " \t\"$gpath\"\n";
165print "\n";
166print " Remember to keep this variable set (correctly) when you want to\n";
167print " use the executables that came with this package.\n";
168print "\n";
b48c75c0 169print " After that you may execute, for example:\n";
4f3224f2 170print "\n";
171print " \t\$ . \$GLOBUS_LOCATION/etc/globus-user-env.sh\n";
172print "\n";
173print " to prepare your environment for running the gsi_openssh\n";
174print " executables.\n";
b48c75c0 175
176if ( !getPrivilegeSeparation() )
177{
178 print "\n";
179 print " o For System Administrators:\n";
180 print "\n";
181 print " If you are going to run the GSI-OpenSSH server, we recommend\n";
182 print " enabling privilege separation. Although this package supports\n";
183 print " this feature, your system appears to require some additional\n";
184 print " configuration.\n";
185 print "\n";
d6ee7a2f 186 print " Perform the following steps to enable privilege separation:\n";
b48c75c0 187 print "\n";
d6ee7a2f 188 print " \t1) If the system user 'sshd' does not already exist, add a\n";
189 print " \t user with that username.\n";
b48c75c0 190 print "\n";
d6ee7a2f 191 print " \t2) Verify that /var/empty exists, is owned by root, and has\n";
192 print " \t a mode of 0700.\n";
b48c75c0 193 print "\n";
d6ee7a2f 194 print " \t3) Enable the feature UsePrivilegeSeparation in\n";
195 print " \t \$GLOBUS_LOCATION/etc/ssh/sshd_config.\n";
b48c75c0 196}
197
e30b893a 198print "\n";
d6ee7a2f 199print " o For more information about GSI-Enabled OpenSSH, visit:\n";
200print " <http://www.ncsa.uiuc.edu/Divisions/ACES/GSI/openssh/>\n";
e30b893a 201
ff3b2ddb 202#
203# give the user a chance to read all of this output
204#
205
206print "\n";
207print "Press <return> to continue... ";
208$trash = <STDIN>;
209
210print "\n";
4f3224f2 211print "---------------------------------------------------------------------\n";
212print "$myname: Finished configuring package 'gsi_openssh'.\n";
213
214exit;
215
216#
217# subroutines
218#
219
7a7884ad 220### initPRNGHash( )
221#
222# initialize the PRNG pathname hash
223#
224
225sub initPRNGHash( )
226{
227 #
228 # standard prng to executable conversion names
229 #
230
231 addPRNGCommand("\@PROG_LS\@", "ls");
232 addPRNGCommand("\@PROG_NETSTAT\@", "netstat");
233 addPRNGCommand("\@PROG_ARP\@", "arp");
234 addPRNGCommand("\@PROG_IFCONFIG\@", "ifconfig");
235 addPRNGCommand("\@PROG_PS\@", "ps");
236 addPRNGCommand("\@PROG_JSTAT\@", "jstat");
237 addPRNGCommand("\@PROG_W\@", "w");
238 addPRNGCommand("\@PROG_WHO\@", "who");
239 addPRNGCommand("\@PROG_LAST\@", "last");
240 addPRNGCommand("\@PROG_LASTLOG\@", "lastlog");
241 addPRNGCommand("\@PROG_DF\@", "df");
242 addPRNGCommand("\@PROG_SAR\@", "sar");
243 addPRNGCommand("\@PROG_VMSTAT\@", "vmstat");
244 addPRNGCommand("\@PROG_UPTIME\@", "uptime");
245 addPRNGCommand("\@PROG_IPCS\@", "ipcs");
246 addPRNGCommand("\@PROG_TAIL\@", "tail");
247
248 print "Determining paths for PRNG commands...\n";
249
250 $paths = determinePRNGPaths();
251
252 return;
253}
254
255### getDirectoryPaths( )
256#
257# return an array ref containing all of the directories in which we should search
258# for our listing of executable names.
259#
260
261sub getDirectoryPaths( )
262{
263 #
264 # read in the PATH environmental variable and prepend a set of 'safe'
265 # directories from which to test PRNG commands.
266 #
267
268 $path = $ENV{PATH};
269 $path = "/bin:/usr/bin:/sbin:/usr/sbin:/etc:" . $path;
270 @dirs = split(/:/, $path);
271
272 #
273 # sanitize each directory listed in the array.
274 #
275
276 @dirs = map {
277 $tmp = $_;
278 $tmp =~ s:/+:/:g;
279 $tmp =~ s:^\s+|\s+$::g;
280 $tmp;
281 } @dirs;
282
283 return \@dirs;
284}
285
286### addPRNGCommand( $prng_name, $exec_name )
287#
288# given a PRNG name and a corresponding executable name, add it to our list of
289# PRNG commands for which to find on the system.
290#
291
292sub addPRNGCommand
293{
294 my($prng_name, $exec_name) = @_;
295
296 prngAddNode($prng_name, $exec_name);
297}
298
299### copyPRNGFile( )
300#
301# read in ssh_prng_cmds.in, translate the program listings to the paths we have
302# found on the local system, and then write the output to ssh_prng_cmds.
303#
304
305sub copyPRNGFile
306{
307 my($fileInput, $fileOutput);
308 my($mode, $uid, $gid);
309 my($data);
310
311 if ( isPresent("/dev/random") && !isForced() )
312 {
313 printf("/dev/random found and not forced. Not installing ssh_prng_cmds...\n");
314 return;
315 }
316
317 initPRNGHash();
318
319 print "Fixing paths in ssh_prng_cmds...\n";
320
321 $fileInput = "$setupdir/ssh_prng_cmds.in";
322 $fileOutput = "$sysconfdir/ssh_prng_cmds";
323
324 #
325 # verify that we are prepared to work with $fileInput
326 #
327
328 if ( !isReadable($fileInput) )
329 {
330 printf("Cannot read $fileInput... skipping.\n");
331 return;
332 }
333
334 #
335 # verify that we are prepared to work with $fileOuput
336 #
337
338 if ( !prepareFileWrite($fileOutput) )
339 {
340 return;
341 }
342
343 #
344 # Grab the current mode/uid/gid for use later
345 #
346
347 $mode = (stat($fileInput))[2];
348 $uid = (stat($fileInput))[4];
349 $gid = (stat($fileInput))[5];
350
351 #
352 # Open the files for reading and writing, and loop over the input's contents
353 #
354
355 $data = readFile($fileInput);
356 for my $k (keys %$prngcmds)
357 {
358 $sub = prngGetExecPath($k);
359 $data =~ s:$k:$sub:g;
360 }
361 writeFile($fileOutput, $data);
362
363 #
364 # An attempt to revert the new file back to the original file's
365 # mode/uid/gid
366 #
367
368 chmod($mode, $fileOutput);
369 chown($uid, $gid, $fileOutput);
370
371 return 0;
372}
373
374### determinePRNGPaths( )
375#
376# for every entry in the PRNG hash, seek out and find the path for the
377# corresponding executable name.
378#
379
380sub determinePRNGPaths
381{
382 my(@paths, @dirs);
383 my($exec_name, $exec_path);
384
385 $dirs = getDirectoryPaths();
386
387 for my $k (keys %$prngcmds)
388 {
389 $exec_name = prngGetExecName($k);
390 $exec_path = findExecutable($exec_name, $dirs);
391 prngSetExecPath($k, $exec_path);
392 }
393
394 return;
395}
396
397### prngAddNode( $prng_name, $exec_name )
398#
399# add a new node to the PRNG hash
400#
401
402sub prngAddNode
403{
404 my($prng_name, $exec_name) = @_;
405 my($node);
406
407 if (!defined($prngcmds))
408 {
409 $prngcmds = {};
410 }
411
412 $node = {};
413 $node->{prng} = $prng_name;
414 $node->{exec} = $exec_name;
415
416 $prngcmds->{$prng_name} = $node;
417}
418
419### prngGetExecName( $key )
420#
421# get the executable name from the prng commands hash named by $key
422#
423
424sub prngGetExecName
425{
426 my($key) = @_;
427
428 return $prngcmds->{$key}->{exec};
429}
430
431### prngGetExecPath( $key )
432#
433# get the executable path from the prng commands hash named by $key
434#
435
436sub prngGetExecPath
437{
438 my($key) = @_;
439
440 return $prngcmds->{$key}->{exec_path};
441}
442
443### prngGetNode( $key )
444#
445# return a reference to the node named by $key
446#
447
448sub prngGetNode
449{
450 my($key) = @_;
451
452 return ${$prngcmds}{$key};
453}
454
455### prngSetExecPath( $key, $path )
456#
457# given a key, set the executable path in that node to $path
458#
459
460sub prngSetExecPath
461{
462 my($key, $path) = @_;
463
464 $prngcmds->{$key}->{exec_path} = $path;
465}
466
467### findExecutable( $exec_name, $dirs )
468#
469# given an executable name, test each possible path in $dirs to see if such
470# an executable exists.
471#
472
473sub findExecutable
474{
475 my($exec_name, $dirs) = @_;
476
477 for my $d (@$dirs)
478 {
479 $test = "$d/$exec_name";
480
481 if ( isExecutable($test) )
482 {
483 return $test;
484 }
485 }
486
487 return "undef";
488}
489
4f3224f2 490### copyKeyFiles( $copylist )
491#
492# given an array of keys to copy, copy both the key and its public variant into
493# the gsi-openssh configuration directory.
494#
495
95f536ac 496sub copyKeyFiles
e9ec5455 497{
95f536ac 498 my($copylist) = @_;
499 my($regex, $basename);
e9ec5455 500
712b003f 501 if (@$copylist)
e9ec5455 502 {
712b003f 503 print "Copying ssh host keys...\n";
e9ec5455 504
712b003f 505 for my $f (@$copylist)
95f536ac 506 {
712b003f 507 $f =~ s:/+:/:g;
508
509 if (length($f) > 0)
510 {
511 $keyfile = "$f";
512 $pubkeyfile = "$f.pub";
95f536ac 513
7a7884ad 514 copyFile("$localsshdir/$keyfile", "$sysconfdir/$keyfile");
515 copyFile("$localsshdir/$pubkeyfile", "$sysconfdir/$pubkeyfile");
712b003f 516 }
95f536ac 517 }
e9ec5455 518 }
e9ec5455 519}
520
7a7884ad 521### isForced( )
522#
523# return true if the user passed in the force flag. return false otherwise.
524#
525
526sub isForced
527{
528 if ( defined($force) && $force )
529 {
530 return 1;
531 }
532 else
533 {
534 return 0;
535 }
536}
537
4f3224f2 538### isReadable( $file )
539#
540# given a file, return true if that file both exists and is readable by the
541# effective user id. return false otherwise.
542#
543
95f536ac 544sub isReadable
1a1f62a4 545{
95f536ac 546 my($file) = @_;
1a1f62a4 547
95f536ac 548 if ( ( -e $file ) && ( -r $file ) )
1a1f62a4 549 {
95f536ac 550 return 1;
1a1f62a4 551 }
823981ba 552 else
1a1f62a4 553 {
95f536ac 554 return 0;
ac083f7a 555 }
1a1f62a4 556}
557
7a7884ad 558### isExecutable( $file )
559#
560# return true if $file is executable. return false otherwise.
561#
562
563sub isExecutable
564{
565 my($file) = @_;
566
567 if ( -x $file )
568 {
569 return 1;
570 }
571 else
572 {
573 return 0;
574 }
575}
576
577### isWritable( $file )
578#
579# given a file, return true if that file does not exist or is writable by the
580# effective user id. return false otherwise.
581#
582
583sub isWritable
584{
585 my($file) = @_;
586
587 if ( ( ! -e $file ) || ( -w $file ) )
588 {
589 return 1;
590 }
591 else
592 {
593 return 0;
594 }
595}
596
4f3224f2 597### isPresent( $file )
598#
599# given a file, return true if that file exists. return false otherwise.
600#
601
712b003f 602sub isPresent
603{
604 my($file) = @_;
605
606 if ( -e $file )
607 {
608 return 1;
609 }
610 else
611 {
612 return 0;
613 }
614}
615
c096bf39 616### makeConfDir( )
617#
618# make the gsi-openssh configuration directory if it doesn't already exist.
619#
620
621sub makeConfDir
622{
623 if ( isPresent($sysconfdir) )
624 {
625 if ( -d $sysconfdir )
626 {
627 return;
628 }
629
630 die("${sysconfdir} already exists and is not a directory!\n");
631 }
632
633 print "Could not find ${sysconfdir} directory... creating.\n";
634 action("mkdir -p $sysconfdir");
635
636 return;
637}
638
4f3224f2 639### determineKeys( )
640#
641# based on a set of key types, triage them to determine if for each key type, that
642# key type should be copied from the main ssh configuration directory, or if it
643# should be generated using ssh-keygen.
644#
645
95f536ac 646sub determineKeys
823981ba 647{
95f536ac 648 my($keyhash, $keylist);
649 my($count);
823981ba 650
712b003f 651 #
652 # initialize our variables
653 #
654
95f536ac 655 $count = 0;
823981ba 656
95f536ac 657 $keyhash = {};
658 $keyhash->{gen} = []; # a list of keytypes to generate
659 $keyhash->{copy} = []; # a list of files to copy from the
712b003f 660
95f536ac 661 $genlist = $keyhash->{gen};
662 $copylist = $keyhash->{copy};
e9ec5455 663
712b003f 664 #
665 # loop over our keytypes and determine what we need to do for each of them
666 #
667
95f536ac 668 for my $keytype (keys %$keyfiles)
1a1f62a4 669 {
95f536ac 670 $basekeyfile = $keyfiles->{$keytype};
1a1f62a4 671
712b003f 672 #
673 # if the key's are already present, we don't need to bother with this rigamarole
674 #
675
676 $gkeyfile = "$sysconfdir/$basekeyfile";
677 $gpubkeyfile = "$sysconfdir/$basekeyfile.pub";
678
679 if ( isPresent($gkeyfile) && isPresent($gpubkeyfile) )
95f536ac 680 {
7a7884ad 681 if ( isForced() )
682 {
683 if ( isWritable("$sysconfdir/$basekeyfile") && isWritable("$sysconfdir/$basekeyfile.pub") )
684 {
685 action("rm $sysconfdir/$basekeyfile");
686 action("rm $sysconfdir/$basekeyfile.pub");
687 }
688 else
689 {
690 next;
691 }
692 }
95f536ac 693 }
1a1f62a4 694
712b003f 695 #
696 # if we can find a copy of the keys in /etc/ssh, we'll copy them to the user's
697 # globus location
698 #
699
700 $mainkeyfile = "$localsshdir/$basekeyfile";
701 $mainpubkeyfile = "$localsshdir/$basekeyfile.pub";
702
703 if ( isReadable($mainkeyfile) && isReadable($mainpubkeyfile) )
95f536ac 704 {
712b003f 705 push(@$copylist, $basekeyfile);
95f536ac 706 $count++;
712b003f 707 next;
95f536ac 708 }
712b003f 709
710 #
711 # otherwise, we need to generate the key
712 #
713
714 push(@$genlist, $keytype);
715 $count++;
1a1f62a4 716 }
717
95f536ac 718 return $keyhash;
719}
720
4f3224f2 721### runKeyGen( $gen_keys )
722#
723# given a set of key types, generate private and public keys for that key type and
724# place them in the gsi-openssh configuration directory.
725#
726
95f536ac 727sub runKeyGen
728{
729 my($gen_keys) = @_;
ce935927 730 my $keygen = "$bindir/ssh-keygen";
95f536ac 731
ce935927 732 if (@$gen_keys && -x $keygen)
1a1f62a4 733 {
712b003f 734 print "Generating ssh host keys...\n";
735
736 for my $k (@$gen_keys)
737 {
738 $keyfile = $keyfiles->{$k};
95f536ac 739
7a7884ad 740 if ( !isPresent("$sysconfdir/$keyfile") )
741 {
742 action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\"");
743 }
712b003f 744 }
1a1f62a4 745 }
746
747 return 0;
748}
749
7a7884ad 750### copySSHDConfigFile( )
5b105785 751#
752# this subroutine 'edits' the paths in sshd_config to suit them to the current environment
753# in which the setup script is being run.
754#
755
7a7884ad 756sub copySSHDConfigFile
20d3226a 757{
5b105785 758 my($fileInput, $fileOutput);
759 my($mode, $uid, $gid);
760 my($line, $newline);
b48c75c0 761 my($privsep_enabled);
823981ba 762
5b105785 763 print "Fixing paths in sshd_config...\n";
95f536ac 764
5b105785 765 $fileInput = "$setupdir/sshd_config.in";
766 $fileOutput = "$sysconfdir/sshd_config";
95f536ac 767
7a7884ad 768 #
769 # verify that we are prepared to work with $fileInput
770 #
771
772 if ( !isReadable($fileInput) )
95f536ac 773 {
7a7884ad 774 printf("Cannot read $fileInput... skipping.\n");
775 return;
5b105785 776 }
777
7a7884ad 778 #
779 # verify that we are prepared to work with $fileOuput
780 #
781
782 if ( !prepareFileWrite($fileOutput) )
5b105785 783 {
7a7884ad 784 return;
95f536ac 785 }
e9ec5455 786
b48c75c0 787 #
788 # check to see whether we should enable privilege separation
789 #
790
791 if ( userExists("sshd") && ( -d "/var/empty" ) && ( getMode("/var/empty") eq "0700" ) )
792 {
793 setPrivilegeSeparation(1);
794 }
795 else
796 {
797 setPrivilegeSeparation(0);
798 }
799
800 if ( getPrivilegeSeparation() )
801 {
802 $privsep_enabled = "yes";
803 }
804 else
805 {
806 $privsep_enabled = "no";
807 }
808
20d3226a 809 #
95f536ac 810 # Grab the current mode/uid/gid for use later
20d3226a 811 #
812
5b105785 813 $mode = (stat($fileInput))[2];
814 $uid = (stat($fileInput))[4];
815 $gid = (stat($fileInput))[5];
20d3226a 816
20d3226a 817 #
5b105785 818 # Open the files for reading and writing, and loop over the input's contents
20d3226a 819 #
820
b48c75c0 821 $data = readFile($fileInput);
20d3226a 822
b48c75c0 823 #
824 # alter the PidFile config
825 #
6193a4af 826
b48c75c0 827 $text = "PidFile\t$gpath/var/sshd.pid";
828 $data =~ s:^[\s|#]*PidFile.*$:$text:gm;
eb4172f6 829
b48c75c0 830 #
831 # set the sftp directive
832 #
7c96a399 833
b48c75c0 834 $text = "Subsystem\tsftp\t$gpath/libxec/sftp-server";
835 $data =~ s:^[\s|#]*Subsystem\s+sftp\s+.*$:$text:gm;
836
837 #
838 # set the privilege separation directive
839 #
840
841 $text = "UsePrivilegeSeparation\t${privsep_enabled}";
842 $data =~ s:^[\s|#]*UsePrivilegeSeparation.*$:$text:gm;
843
844 #
845 # dump the modified output to the config file
846 #
847
848 writeFile($fileOutput, $data);
7c96a399 849
95f536ac 850 #
851 # An attempt to revert the new file back to the original file's
852 # mode/uid/gid
853 #
7e12c9a7 854
5b105785 855 chmod($mode, $fileOutput);
856 chown($uid, $gid, $fileOutput);
20d3226a 857
858 return 0;
859}
860
b48c75c0 861### setPrivilegeSeparation( $value )
862#
863# set the privilege separation variable to $value
864#
865
866sub setPrivilegeSeparation
867{
868 my($value) = @_;
869
870 $privsep = $value;
871}
872
873### getPrivilegeSeparation( )
874#
875# return the value of the privilege separation variable
876#
877
878sub getPrivilegeSeparation
879{
880 return $privsep;
881}
882
7a7884ad 883### prepareFileWrite( $file )
884#
885# test $file to prepare for writing to it.
886#
887
888sub prepareFileWrite
889{
890 my($file) = @_;
891
892 if ( isPresent($file) )
893 {
894 printf("$file already exists... ");
895
896 if ( isForced() )
897 {
898 if ( isWritable($file) )
899 {
900 printf("removing.\n");
901 action("rm $file");
902 return 1;
903 }
904 else
905 {
906 printf("not writable -- skipping.\n");
907 return 0;
908 }
909 }
910 else
911 {
912 printf("skipping.\n");
913 return 0;
914 }
915 }
916
917 return 1;
918}
919
5b105785 920### copyConfigFiles( )
921#
922# subroutine that copies some extra config files to their proper location in
923# $GLOBUS_LOCATION/etc/ssh.
924#
925
926sub copyConfigFiles
927{
7a7884ad 928 #
929 # copy the sshd_config file into the ssh configuration directory and alter
930 # the paths in the file.
931 #
932
933 copySSHDConfigFile();
934
935 #
936 # do straight copies of the ssh_config and moduli files.
937 #
938
939 printf("Copying ssh_config and moduli to their proper location...\n");
940
941 copyFile("$setupdir/ssh_config", "$sysconfdir/ssh_config");
942 copyFile("$setupdir/moduli", "$sysconfdir/moduli");
5b105785 943
7a7884ad 944 #
945 # copy and alter the SXXsshd script.
946 #
947
948 copySXXScript("$setupdir/SXXsshd.in", "$sbindir/SXXsshd");
5b105785 949}
950
7a7884ad 951### copyFile( $src, $dest )
4f3224f2 952#
7a7884ad 953# copy the file pointed to by $src to the location specified by $dest. in the
954# process observe the rules regarding when the '-force' flag was passed to us.
4f3224f2 955#
956
7a7884ad 957sub copyFile
a26c150d 958{
7a7884ad 959 my($src, $dest) = @_;
d58b3a33 960
7a7884ad 961 if ( !isReadable($src) )
20bb6dc8 962 {
7a7884ad 963 printf("$src is not readable... not creating $dest.\n");
964 return;
20bb6dc8 965 }
7a7884ad 966
967 if ( !prepareFileWrite($dest) )
968 {
969 return;
970 }
971
972 action("cp $src $dest");
d58b3a33 973}
974
7a7884ad 975### copySXXScript( $in, $out )
4f3224f2 976#
7a7884ad 977# parse the input file, substituting in place the value of GLOBUS_LOCATION, and
978# write the result to the output file.
4f3224f2 979#
980
7a7884ad 981sub copySXXScript
d58b3a33 982{
7a7884ad 983 my($in, $out) = @_;
984
985 if ( !isReadable($in) )
986 {
987 printf("$in is not readable... not creating $out.\n");
988 return;
989 }
990
991 if ( !prepareFileWrite($out) )
992 {
993 return;
994 }
995
996 $data = readFile($in);
997 $data =~ s|\@GLOBUS_LOCATION\@|$gpath|g;
998 writeFile($out, $data);
999 action("chmod 755 $out");
a26c150d 1000}
1001
1002### readFile( $filename )
1003#
1004# reads and returns $filename's contents
1005#
1006
1007sub readFile
1008{
7a7884ad 1009 my($filename) = @_;
1010 my($data);
a26c150d 1011
7a7884ad 1012 open(IN, "$filename") || die "Can't open '$filename': $!";
a26c150d 1013 $/ = undef;
1014 $data = <IN>;
1015 $/ = "\n";
1016 close(IN);
1017
1018 return $data;
1019}
1020
1021### writeFile( $filename, $fileinput )
1022#
1023# create the inputs to the ssl program at $filename, appending the common name to the
1024# stream in the process
1025#
1026
1027sub writeFile
1028{
7a7884ad 1029 my($filename, $fileinput) = @_;
a26c150d 1030
1031 #
1032 # test for a valid $filename
1033 #
1034
1035 if ( !defined($filename) || (length($filename) lt 1) )
1036 {
1037 die "Filename is undefined";
1038 }
1039
7a7884ad 1040 #
1041 # verify that we are prepared to work with $filename
1042 #
1043
1044 if ( !prepareFileWrite($filename) )
a26c150d 1045 {
7a7884ad 1046 return;
a26c150d 1047 }
1048
1049 #
1050 # write the output to $filename
1051 #
1052
1053 open(OUT, ">$filename");
1054 print OUT "$fileinput";
1055 close(OUT);
1056}
1057
7a7884ad 1058### action( $command )
ac083f7a 1059#
7a7884ad 1060# run $command within a proper system() command.
ac083f7a 1061#
1062
1063sub action
1064{
7a7884ad 1065 my($command) = @_;
ac083f7a 1066
1067 printf "$command\n";
1068
8b73e3d0 1069 my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1");
ac083f7a 1070
1071 if (($result or $?) and $command !~ m!patch!)
1072 {
1073 die "ERROR: Unable to execute command: $!\n";
1074 }
1075}
1076
7a7884ad 1077### query_boolean( $query_text, $default )
1078#
1079# query the user with a string, and expect a response. If the user hits
1080# 'enter' instead of entering an input, then accept the default response.
1081#
1082
ac083f7a 1083sub query_boolean
1084{
7a7884ad 1085 my($query_text, $default) = @_;
1086 my($nondefault, $foo, $bar);
ac083f7a 1087
1088 #
1089 # Set $nondefault to the boolean opposite of $default.
1090 #
1091
1092 if ($default eq "n")
1093 {
1094 $nondefault = "y";
1095 }
1096 else
1097 {
1098 $nondefault = "n";
1099 }
1100
1101 print "${query_text} ";
1102 print "[$default] ";
1103
e9ec5455 1104 $foo = <STDIN>;
1105 ($bar) = split //, $foo;
1106
e9d69a89 1107 if ( grep(/\s/, $bar) )
ac083f7a 1108 {
e9d69a89 1109 # this is debatable. all whitespace means 'default'
1110
1111 $bar = $default;
1112 }
1113 elsif ($bar ne $default)
1114 {
1115 # everything else means 'nondefault'.
1116
1117 $bar = $nondefault;
1118 }
1119 else
1120 {
1121 # extraneous step. to get here, $bar should be eq to $default anyway.
1122
e9ec5455 1123 $bar = $default;
ac083f7a 1124 }
1125
e9ec5455 1126 return $bar;
ac083f7a 1127}
c096bf39 1128
1129### absolutePath( $file )
1130#
1131# converts a given pathname into a canonical path using the abs_path function.
1132#
1133
1134sub absolutePath
1135{
1136 my($file) = @_;
1137 my $home = $ENV{'HOME'};
1138 $file =~ s!~!$home!;
1139 my $startd = cwd();
1140 $file =~ s!^\./!$startd/!;
1141 $file = "$startd/$file" if $file !~ m!^\s*/!;
1142 $file = abs_path($file);
1143 return $file;
1144}
b48c75c0 1145
1146### getMode( $file )
1147#
1148# return a string containing the mode of the given file.
1149#
1150
1151sub getMode
1152{
1153 my($file) = @_;
1154 my($tempmode, $mode);
1155
1156 #
1157 # call stat() to get the mode of the file
1158 #
1159
1160 $tempmode = (stat($file))[2];
1161 if (length($tempmode) < 1)
1162 {
1163 return "";
1164 }
1165
1166 #
1167 # call sprintf to format the mode into a UNIX-like string
1168 #
1169
1170 $mode = sprintf("%04o", $tempmode & 07777);
1171
1172 return $mode;
1173}
1174
1175### userExists( $username )
1176#
1177# given a username, return true if the user exists on the system. return false
1178# otherwise.
1179#
1180
1181sub userExists
1182{
1183 my($username) = @_;
1184 my($uid);
1185
1186 #
1187 # retrieve the userid of the user with the given username
1188 #
1189
1190 $uid = getpwnam($username);
1191
1192 #
1193 # return true if $uid is defined and has a length greater than 0
1194 #
1195
1196 if ( defined($uid) and (length($uid) > 0) )
1197 {
1198 return 1;
1199 }
1200 else
1201 {
1202 return 0;
1203 }
1204}
This page took 0.748369 seconds and 5 git commands to generate.