]> andersk Git - gssapi-openssh.git/blob - setup/setup-openssh.pl
o Initialize privilege separation setting at the beginning of the script
[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
1001     if ( !isReadable($in) )
1002     {
1003         printf("$in is not readable... not creating $out.\n");
1004         return;
1005     }
1006
1007     if ( !prepareFileWrite($out) )
1008     {
1009         return;
1010     }
1011
1012     $data = readFile($in);
1013     $data =~ s|\@GLOBUS_LOCATION\@|$gpath|g;
1014     writeFile($out, $data);
1015     action("chmod 755 $out");
1016 }
1017
1018 ### readFile( $filename )
1019 #
1020 # reads and returns $filename's contents
1021 #
1022
1023 sub readFile
1024 {
1025     my($filename) = @_;
1026     my($data);
1027
1028     open(IN, "$filename") || die "Can't open '$filename': $!";
1029     $/ = undef;
1030     $data = <IN>;
1031     $/ = "\n";
1032     close(IN);
1033
1034     return $data;
1035 }
1036
1037 ### writeFile( $filename, $fileinput )
1038 #
1039 # create the inputs to the ssl program at $filename, appending the common name to the
1040 # stream in the process
1041 #
1042
1043 sub writeFile
1044 {
1045     my($filename, $fileinput) = @_;
1046
1047     #
1048     # test for a valid $filename
1049     #
1050
1051     if ( !defined($filename) || (length($filename) lt 1) )
1052     {
1053         die "Filename is undefined";
1054     }
1055
1056     #
1057     # verify that we are prepared to work with $filename
1058     #
1059
1060     if ( !prepareFileWrite($filename) )
1061     {
1062         return;
1063     }
1064
1065     #
1066     # write the output to $filename
1067     #
1068
1069     open(OUT, ">$filename");
1070     print OUT "$fileinput";
1071     close(OUT);
1072 }
1073
1074 ### action( $command )
1075 #
1076 # run $command within a proper system() command.
1077 #
1078
1079 sub action
1080 {
1081     my($command) = @_;
1082
1083     printf "$command\n";
1084
1085     my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1");
1086
1087     if (($result or $?) and $command !~ m!patch!)
1088     {
1089         die "ERROR: Unable to execute command: $!\n";
1090     }
1091 }
1092
1093 ### query_boolean( $query_text, $default )
1094 #
1095 # query the user with a string, and expect a response.  If the user hits
1096 # 'enter' instead of entering an input, then accept the default response.
1097 #
1098
1099 sub query_boolean
1100 {
1101     my($query_text, $default) = @_;
1102     my($nondefault, $foo, $bar);
1103
1104     #
1105     # Set $nondefault to the boolean opposite of $default.
1106     #
1107
1108     if ($default eq "n")
1109     {
1110         $nondefault = "y";
1111     }
1112     else
1113     {
1114         $nondefault = "n";
1115     }
1116
1117     print "${query_text} ";
1118     print "[$default] ";
1119
1120     $foo = <STDIN>;
1121     ($bar) = split //, $foo;
1122
1123     if ( grep(/\s/, $bar) )
1124     {
1125         # this is debatable.  all whitespace means 'default'
1126
1127         $bar = $default;
1128     }
1129     elsif ($bar ne $default)
1130     {
1131         # everything else means 'nondefault'.
1132
1133         $bar = $nondefault;
1134     }
1135     else
1136     {
1137         # extraneous step.  to get here, $bar should be eq to $default anyway.
1138
1139         $bar = $default;
1140     }
1141
1142     return $bar;
1143 }
1144
1145 ### absolutePath( $file )
1146 #
1147 # converts a given pathname into a canonical path using the abs_path function.
1148 #
1149
1150 sub absolutePath
1151 {
1152     my($file) = @_;
1153     my $home = $ENV{'HOME'};
1154     $file =~ s!~!$home!;
1155     my $startd = cwd();
1156     $file =~ s!^\./!$startd/!;
1157     $file = "$startd/$file" if $file !~ m!^\s*/!;
1158     $file = abs_path($file);
1159     return $file;
1160 }
1161
1162 ### getOwnerID( $file )
1163 #
1164 # return the uid containing the owner ID of the given file.
1165 #
1166
1167 sub getOwnerID
1168 {
1169     my($file) = @_;
1170     my($uid);
1171
1172     #
1173     # call stat() to get the mode of the file
1174     #
1175
1176     $uid = (stat($file))[4];
1177
1178     return $uid;
1179 }
1180
1181 ### getMode( $file )
1182 #
1183 # return a string containing the mode of the given file.
1184 #
1185
1186 sub getMode
1187 {
1188     my($file) = @_;
1189     my($tempmode, $mode);
1190
1191     #
1192     # call stat() to get the mode of the file
1193     #
1194
1195     $tempmode = (stat($file))[2];
1196     if (length($tempmode) < 1)
1197     {
1198         return "";
1199     }
1200
1201     #
1202     # call sprintf to format the mode into a UNIX-like string
1203     #
1204
1205     $mode = sprintf("%04o", $tempmode & 07777);
1206
1207     return $mode;
1208 }
1209
1210 ### userExists( $username )
1211 #
1212 # given a username, return true if the user exists on the system.  return false
1213 # otherwise.
1214 #
1215
1216 sub userExists
1217 {
1218     my($username) = @_;
1219     my($uid);
1220
1221     #
1222     # retrieve the userid of the user with the given username
1223     #
1224
1225     $uid = getpwnam($username);
1226
1227     #
1228     # return true if $uid is defined and has a length greater than 0
1229     #
1230
1231     if ( defined($uid) and (length($uid) > 0) )
1232     {
1233         return 1;
1234     }
1235     else
1236     {
1237         return 0;
1238     }
1239 }
This page took 0.138835 seconds and 5 git commands to generate.