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