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