]> andersk Git - gssapi-openssh.git/blame - setup/setup-openssh.pl
o Just in case check-in to bring all exits in-line with a standard exit
[gssapi-openssh.git] / setup / setup-openssh.pl
CommitLineData
7a7884ad 1#!/usr/bin/perl
20d3226a 2#
5002372c 3# setup-openssh.pl
4#
95f536ac 5# Adapts the installed gsi-openssh environment to the current machine,
5002372c 6# performing actions that originally occurred during the package's
7# 'make install' phase.
701aa556 8#
1eab725d 9# Send comments/fixes/suggestions to:
10# Chase Phillips <cphillip@ncsa.uiuc.edu>
701aa556 11#
20d3226a 12
7e12c9a7 13#
14# Get user's GPT_LOCATION since we may be installing this using a new(er)
15# version of GPT.
16#
17
18$gptpath = $ENV{GPT_LOCATION};
19
20#
21# And the old standby..
22#
23
4f276ad7 24$gpath = $ENV{GLOBUS_LOCATION};
ad71c979 25if (!defined($gpath))
26{
74d5d582 27 exitDie "GLOBUS_LOCATION needs to be set before running this script"
ad71c979 28}
29
7a7884ad 30#
31# Include standard modules
32#
33
34use Getopt::Long;
35use Cwd;
36use Cwd 'abs_path';
37
8b73e3d0 38#
39# modify the ld library path for when we call ssh executables
40#
41
42$oldldpath = $ENV{LD_LIBRARY_PATH};
43$newldpath = "$gpath/lib";
44if (length($oldldpath) > 0)
45{
46 $newldpath .= ":$oldldpath";
47}
48$ENV{LD_LIBRARY_PATH} = "$newldpath";
49
ad71c979 50#
51# i'm including this because other perl scripts in the gpt setup directories
52# do so
53#
54
7e12c9a7 55if (defined($gptpath))
56{
57 @INC = (@INC, "$gptpath/lib/perl", "$gpath/lib/perl");
58}
59else
60{
61 @INC = (@INC, "$gpath/lib/perl");
62}
ad71c979 63
4f276ad7 64require Grid::GPT::Setup;
65
7a7884ad 66#
67# script-centred variable initialization
68#
69
ad71c979 70my $globusdir = $gpath;
ad71c979 71my $myname = "setup-openssh.pl";
72
20d3226a 73#
74# Set up path prefixes for use in the path translations
75#
76
d0a1bda7 77$prefix = ${globusdir};
78$exec_prefix = "${prefix}";
79$bindir = "${exec_prefix}/bin";
9cc10d0e 80$sbindir = "${exec_prefix}/sbin";
95f536ac 81$sysconfdir = "$prefix/etc/ssh";
82$localsshdir = "/etc/ssh";
20bb6dc8 83$setupdir = "$prefix/setup/gsi_openssh_setup";
e9ec5455 84
7a7884ad 85#
86# standard key types and their root file name mappings
87#
88
95f536ac 89my $keyfiles = {
90 "dsa" => "ssh_host_dsa_key",
91 "rsa" => "ssh_host_rsa_key",
92 "rsa1" => "ssh_host_key",
93 };
823981ba 94
7a7884ad 95#
96# argument specification. we offload some processing work from later functions
97# to verify correct args by using anon subs in various places.
98#
99
571ab952 100my($prompt, $force, $verbose);
7a7884ad 101
bf1ee591 102$prompt = 1;
103
7a7884ad 104GetOptions(
571ab952 105 'prompt!' => \$prompt,
7a7884ad 106 'force' => \$force,
107 'verbose' => \$verbose,
108 ) or pod2usage(2);
109
2c034b75 110#
111# miscellaneous initialization functions
112#
113
114setPrivilegeSeparation(0);
115
7a7884ad 116#
117# main execution. This should find its way into a subroutine at some future
118# point.
119#
120
4f3224f2 121print "$myname: Configuring package 'gsi_openssh'...\n";
122print "---------------------------------------------------------------------\n";
70d921fc 123print "Hi, I'm the setup script for the gsi_openssh package! I will create\n";
124print "a number of configuration files based on your local system setup. I\n";
125print "will also attempt to copy or create a number of SSH key pairs for\n";
b48c75c0 126print "this machine. (Loosely, if I find a pair of host keys in /etc/ssh,\n";
127print "I will copy them into \$GLOBUS_LOCATION/etc/ssh. Otherwise, I will\n";
128print "generate them for you.)\n";
4f3224f2 129print "\n";
4f3224f2 130
70d921fc 131if ( 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
4f3224f2 141$response = query_boolean("Do you wish to continue with the setup package?","y");
142if ($response eq "n")
143{
144 print "\n";
145 print "Exiting gsi_openssh setup.\n";
146
802b9083 147 exit;
4f3224f2 148}
149
150print "\n";
151
152makeConfDir();
614e6d8b 153copyPRNGFile();
4f3224f2 154$keyhash = determineKeys();
155runKeyGen($keyhash->{gen});
156copyKeyFiles($keyhash->{copy});
4f3224f2 157copyConfigFiles();
4f3224f2 158
159my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup");
160
161$metadata->finish();
162
163print "\n";
164print "Additional Notes:\n";
165print "\n";
166print " o I see that you have your GLOBUS_LOCATION environmental variable\n";
167print " set to:\n";
168print "\n";
fd2eb2b2 169print " \"$gpath\"\n";
4f3224f2 170print "\n";
171print " Remember to keep this variable set (correctly) when you want to\n";
172print " use the executables that came with this package.\n";
173print "\n";
b48c75c0 174print " After that you may execute, for example:\n";
4f3224f2 175print "\n";
fd2eb2b2 176print " \$ . \$GLOBUS_LOCATION/etc/globus-user-env.sh\n";
4f3224f2 177print "\n";
178print " to prepare your environment for running the gsi_openssh\n";
179print " executables.\n";
20939b02 180print "\n";
181print " o I recommend you review and customize to your liking the contents of\n";
182print "\n";
183print " \$GLOBUS_LOCATION/etc/ssh\n";
184print "\n";
185print " \"I can only show you the door. You have to walk through it.\"\n";
b48c75c0 186
187if ( !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";
fd2eb2b2 197 print " From the file README.privsep, included as a part of the OpenSSH\n";
198 print " distribution:\n";
b48c75c0 199 print "\n";
8c2b2cf1 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";
fd2eb2b2 204 print " daemons, and must be locked and should contain a \"nologin\"\n";
205 print " or invalid shell.\n";
b48c75c0 206 print "\n";
fd2eb2b2 207 print " You should do something like the following to prepare the\n";
208 print " privsep preauth environment:\n";
b48c75c0 209 print "\n";
fd2eb2b2 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";
b48c75c0 218}
219
e30b893a 220print "\n";
d6ee7a2f 221print " o For more information about GSI-Enabled OpenSSH, visit:\n";
e53e0bb3 222print " <http://grid.ncsa.uiuc.edu/ssh/>\n";
e30b893a 223
ff3b2ddb 224#
225# give the user a chance to read all of this output
226#
227
bf1ee591 228if ( $prompt )
571ab952 229{
230 print "\n";
231 print "Press <return> to continue... ";
232 $trash = <STDIN>;
233}
ff3b2ddb 234
4f3224f2 235print "---------------------------------------------------------------------\n";
236print "$myname: Finished configuring package 'gsi_openssh'.\n";
237
238exit;
239
240#
241# subroutines
242#
243
7a7884ad 244### initPRNGHash( )
245#
246# initialize the PRNG pathname hash
247#
248
249sub 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
285sub 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
316sub 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
329sub copyPRNGFile
330{
331 my($fileInput, $fileOutput);
332 my($mode, $uid, $gid);
333 my($data);
334
64545db1 335 if ( isPresent("$sysconfdir/ssh_prng_cmds") && !isForced() )
7a7884ad 336 {
64545db1 337 printf("ssh_prng_cmds found and not forced. Not installing ssh_prng_cmds...\n");
7a7884ad 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
404sub 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
426sub 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
448sub 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
460sub 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
472sub 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
484sub 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
497sub 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
4f3224f2 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
95f536ac 520sub copyKeyFiles
e9ec5455 521{
95f536ac 522 my($copylist) = @_;
523 my($regex, $basename);
e9ec5455 524
712b003f 525 if (@$copylist)
e9ec5455 526 {
712b003f 527 print "Copying ssh host keys...\n";
e9ec5455 528
712b003f 529 for my $f (@$copylist)
95f536ac 530 {
712b003f 531 $f =~ s:/+:/:g;
532
533 if (length($f) > 0)
534 {
535 $keyfile = "$f";
536 $pubkeyfile = "$f.pub";
95f536ac 537
7a7884ad 538 copyFile("$localsshdir/$keyfile", "$sysconfdir/$keyfile");
539 copyFile("$localsshdir/$pubkeyfile", "$sysconfdir/$pubkeyfile");
712b003f 540 }
95f536ac 541 }
e9ec5455 542 }
e9ec5455 543}
544
7a7884ad 545### isForced( )
546#
547# return true if the user passed in the force flag. return false otherwise.
548#
549
550sub isForced
551{
552 if ( defined($force) && $force )
553 {
554 return 1;
555 }
556 else
557 {
558 return 0;
559 }
560}
561
4f3224f2 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
95f536ac 568sub isReadable
1a1f62a4 569{
95f536ac 570 my($file) = @_;
1a1f62a4 571
95f536ac 572 if ( ( -e $file ) && ( -r $file ) )
1a1f62a4 573 {
95f536ac 574 return 1;
1a1f62a4 575 }
823981ba 576 else
1a1f62a4 577 {
95f536ac 578 return 0;
ac083f7a 579 }
1a1f62a4 580}
581
7a7884ad 582### isExecutable( $file )
583#
584# return true if $file is executable. return false otherwise.
585#
586
587sub 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
607sub 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
4f3224f2 621### isPresent( $file )
622#
623# given a file, return true if that file exists. return false otherwise.
624#
625
712b003f 626sub isPresent
627{
628 my($file) = @_;
629
630 if ( -e $file )
631 {
632 return 1;
633 }
634 else
635 {
636 return 0;
637 }
638}
639
c096bf39 640### makeConfDir( )
641#
642# make the gsi-openssh configuration directory if it doesn't already exist.
643#
644
645sub makeConfDir
646{
647 if ( isPresent($sysconfdir) )
648 {
649 if ( -d $sysconfdir )
650 {
651 return;
652 }
653
74d5d582 654 print("${sysconfdir} already exists and is not a directory!\n");
655 exit;
c096bf39 656 }
657
658 print "Could not find ${sysconfdir} directory... creating.\n";
659 action("mkdir -p $sysconfdir");
660
661 return;
662}
663
4f3224f2 664### determineKeys( )
665#
666# based on a set of key types, triage them to determine if for each key type, that
667# key type should be copied from the main ssh configuration directory, or if it
668# should be generated using ssh-keygen.
669#
670
95f536ac 671sub determineKeys
823981ba 672{
95f536ac 673 my($keyhash, $keylist);
674 my($count);
823981ba 675
712b003f 676 #
677 # initialize our variables
678 #
679
95f536ac 680 $count = 0;
823981ba 681
95f536ac 682 $keyhash = {};
683 $keyhash->{gen} = []; # a list of keytypes to generate
684 $keyhash->{copy} = []; # a list of files to copy from the
712b003f 685
95f536ac 686 $genlist = $keyhash->{gen};
687 $copylist = $keyhash->{copy};
e9ec5455 688
712b003f 689 #
690 # loop over our keytypes and determine what we need to do for each of them
691 #
692
95f536ac 693 for my $keytype (keys %$keyfiles)
1a1f62a4 694 {
95f536ac 695 $basekeyfile = $keyfiles->{$keytype};
1a1f62a4 696
712b003f 697 #
698 # if the key's are already present, we don't need to bother with this rigamarole
699 #
700
701 $gkeyfile = "$sysconfdir/$basekeyfile";
702 $gpubkeyfile = "$sysconfdir/$basekeyfile.pub";
703
704 if ( isPresent($gkeyfile) && isPresent($gpubkeyfile) )
95f536ac 705 {
7a7884ad 706 if ( isForced() )
707 {
708 if ( isWritable("$sysconfdir/$basekeyfile") && isWritable("$sysconfdir/$basekeyfile.pub") )
709 {
710 action("rm $sysconfdir/$basekeyfile");
711 action("rm $sysconfdir/$basekeyfile.pub");
712 }
713 else
714 {
715 next;
716 }
717 }
95f536ac 718 }
1a1f62a4 719
712b003f 720 #
721 # if we can find a copy of the keys in /etc/ssh, we'll copy them to the user's
722 # globus location
723 #
724
725 $mainkeyfile = "$localsshdir/$basekeyfile";
726 $mainpubkeyfile = "$localsshdir/$basekeyfile.pub";
727
728 if ( isReadable($mainkeyfile) && isReadable($mainpubkeyfile) )
95f536ac 729 {
712b003f 730 push(@$copylist, $basekeyfile);
95f536ac 731 $count++;
712b003f 732 next;
95f536ac 733 }
712b003f 734
735 #
736 # otherwise, we need to generate the key
737 #
738
739 push(@$genlist, $keytype);
740 $count++;
1a1f62a4 741 }
742
95f536ac 743 return $keyhash;
744}
745
4f3224f2 746### runKeyGen( $gen_keys )
747#
748# given a set of key types, generate private and public keys for that key type and
749# place them in the gsi-openssh configuration directory.
750#
751
95f536ac 752sub runKeyGen
753{
754 my($gen_keys) = @_;
ce935927 755 my $keygen = "$bindir/ssh-keygen";
95f536ac 756
ce935927 757 if (@$gen_keys && -x $keygen)
1a1f62a4 758 {
712b003f 759 print "Generating ssh host keys...\n";
760
761 for my $k (@$gen_keys)
762 {
763 $keyfile = $keyfiles->{$k};
95f536ac 764
7a7884ad 765 if ( !isPresent("$sysconfdir/$keyfile") )
766 {
767 action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\"");
768 }
712b003f 769 }
1a1f62a4 770 }
771
772 return 0;
773}
774
7a7884ad 775### copySSHDConfigFile( )
5b105785 776#
777# this subroutine 'edits' the paths in sshd_config to suit them to the current environment
778# in which the setup script is being run.
779#
780
7a7884ad 781sub copySSHDConfigFile
20d3226a 782{
5b105785 783 my($fileInput, $fileOutput);
784 my($mode, $uid, $gid);
785 my($line, $newline);
b48c75c0 786 my($privsep_enabled);
823981ba 787
5b105785 788 print "Fixing paths in sshd_config...\n";
95f536ac 789
5b105785 790 $fileInput = "$setupdir/sshd_config.in";
791 $fileOutput = "$sysconfdir/sshd_config";
95f536ac 792
7a7884ad 793 #
794 # verify that we are prepared to work with $fileInput
795 #
796
797 if ( !isReadable($fileInput) )
95f536ac 798 {
7a7884ad 799 printf("Cannot read $fileInput... skipping.\n");
800 return;
5b105785 801 }
802
7a7884ad 803 #
804 # verify that we are prepared to work with $fileOuput
805 #
806
807 if ( !prepareFileWrite($fileOutput) )
5b105785 808 {
7a7884ad 809 return;
95f536ac 810 }
e9ec5455 811
b48c75c0 812 #
813 # check to see whether we should enable privilege separation
814 #
815
8c2b2cf1 816 if ( userExists("sshd") && ( -d "/var/empty" ) && ( getOwnerID("/var/empty") eq 0 ) )
b48c75c0 817 {
818 setPrivilegeSeparation(1);
819 }
820 else
821 {
822 setPrivilegeSeparation(0);
823 }
824
825 if ( getPrivilegeSeparation() )
826 {
827 $privsep_enabled = "yes";
828 }
829 else
830 {
831 $privsep_enabled = "no";
832 }
833
20d3226a 834 #
95f536ac 835 # Grab the current mode/uid/gid for use later
20d3226a 836 #
837
5b105785 838 $mode = (stat($fileInput))[2];
839 $uid = (stat($fileInput))[4];
840 $gid = (stat($fileInput))[5];
20d3226a 841
20d3226a 842 #
5b105785 843 # Open the files for reading and writing, and loop over the input's contents
20d3226a 844 #
845
b48c75c0 846 $data = readFile($fileInput);
20d3226a 847
fb6517a6 848 # #
849 # # alter the PidFile config
850 # #
851 #
852 # $text = "PidFile\t$gpath/var/sshd.pid";
853 # $data =~ s:^[\s|#]*PidFile.*$:$text:gm;
eb4172f6 854
b48c75c0 855 #
856 # set the sftp directive
857 #
7c96a399 858
b84327f8 859 $text = "Subsystem\tsftp\t$gpath/libexec/sftp-server";
b48c75c0 860 $data =~ s:^[\s|#]*Subsystem\s+sftp\s+.*$:$text:gm;
861
862 #
863 # set the privilege separation directive
864 #
865
866 $text = "UsePrivilegeSeparation\t${privsep_enabled}";
867 $data =~ s:^[\s|#]*UsePrivilegeSeparation.*$:$text:gm;
868
869 #
870 # dump the modified output to the config file
871 #
872
873 writeFile($fileOutput, $data);
7c96a399 874
95f536ac 875 #
876 # An attempt to revert the new file back to the original file's
877 # mode/uid/gid
878 #
7e12c9a7 879
5b105785 880 chmod($mode, $fileOutput);
881 chown($uid, $gid, $fileOutput);
20d3226a 882
883 return 0;
884}
885
b48c75c0 886### setPrivilegeSeparation( $value )
887#
888# set the privilege separation variable to $value
889#
890
891sub setPrivilegeSeparation
892{
893 my($value) = @_;
894
895 $privsep = $value;
896}
897
898### getPrivilegeSeparation( )
899#
900# return the value of the privilege separation variable
901#
902
903sub getPrivilegeSeparation
904{
905 return $privsep;
906}
907
7a7884ad 908### prepareFileWrite( $file )
909#
910# test $file to prepare for writing to it.
911#
912
913sub prepareFileWrite
914{
915 my($file) = @_;
916
917 if ( isPresent($file) )
918 {
919 printf("$file already exists... ");
920
921 if ( isForced() )
922 {
923 if ( isWritable($file) )
924 {
925 printf("removing.\n");
926 action("rm $file");
927 return 1;
928 }
929 else
930 {
931 printf("not writable -- skipping.\n");
932 return 0;
933 }
934 }
935 else
936 {
937 printf("skipping.\n");
938 return 0;
939 }
940 }
941
942 return 1;
943}
944
5b105785 945### copyConfigFiles( )
946#
947# subroutine that copies some extra config files to their proper location in
948# $GLOBUS_LOCATION/etc/ssh.
949#
950
951sub copyConfigFiles
952{
7a7884ad 953 #
954 # copy the sshd_config file into the ssh configuration directory and alter
955 # the paths in the file.
956 #
957
958 copySSHDConfigFile();
959
960 #
961 # do straight copies of the ssh_config and moduli files.
962 #
963
964 printf("Copying ssh_config and moduli to their proper location...\n");
965
966 copyFile("$setupdir/ssh_config", "$sysconfdir/ssh_config");
967 copyFile("$setupdir/moduli", "$sysconfdir/moduli");
5b105785 968
7a7884ad 969 #
970 # copy and alter the SXXsshd script.
971 #
972
973 copySXXScript("$setupdir/SXXsshd.in", "$sbindir/SXXsshd");
5b105785 974}
975
7a7884ad 976### copyFile( $src, $dest )
4f3224f2 977#
7a7884ad 978# copy the file pointed to by $src to the location specified by $dest. in the
979# process observe the rules regarding when the '-force' flag was passed to us.
4f3224f2 980#
981
7a7884ad 982sub copyFile
a26c150d 983{
7a7884ad 984 my($src, $dest) = @_;
d58b3a33 985
7a7884ad 986 if ( !isReadable($src) )
20bb6dc8 987 {
7a7884ad 988 printf("$src is not readable... not creating $dest.\n");
989 return;
20bb6dc8 990 }
7a7884ad 991
992 if ( !prepareFileWrite($dest) )
993 {
994 return;
995 }
996
997 action("cp $src $dest");
d58b3a33 998}
999
7a7884ad 1000### copySXXScript( $in, $out )
4f3224f2 1001#
7a7884ad 1002# parse the input file, substituting in place the value of GLOBUS_LOCATION, and
1003# write the result to the output file.
4f3224f2 1004#
1005
7a7884ad 1006sub copySXXScript
d58b3a33 1007{
7a7884ad 1008 my($in, $out) = @_;
b1282c82 1009 my($tmpgpath);
7a7884ad 1010
1011 if ( !isReadable($in) )
1012 {
1013 printf("$in is not readable... not creating $out.\n");
1014 return;
1015 }
1016
1017 if ( !prepareFileWrite($out) )
1018 {
1019 return;
1020 }
1021
b1282c82 1022 #
1023 # clean up any junk in the globus path variable
1024 #
1025
1026 $tmpgpath = $gpath;
1027 $tmpgpath =~ s:/+:/:g;
1028 $tmpgpath =~ s:([^/]+)/$:\1:g;
1029
1030 #
1031 # read in the script, substitute globus location, then write it back out
1032 #
1033
7a7884ad 1034 $data = readFile($in);
b1282c82 1035 $data =~ s|\@GLOBUS_LOCATION\@|$tmpgpath|g;
7a7884ad 1036 writeFile($out, $data);
1037 action("chmod 755 $out");
a26c150d 1038}
1039
1040### readFile( $filename )
1041#
1042# reads and returns $filename's contents
1043#
1044
1045sub readFile
1046{
7a7884ad 1047 my($filename) = @_;
1048 my($data);
a26c150d 1049
74d5d582 1050 open(IN, "$filename") || exitDie "Can't open '$filename': $!";
a26c150d 1051 $/ = undef;
1052 $data = <IN>;
1053 $/ = "\n";
1054 close(IN);
1055
1056 return $data;
1057}
1058
1059### writeFile( $filename, $fileinput )
1060#
1061# create the inputs to the ssl program at $filename, appending the common name to the
1062# stream in the process
1063#
1064
1065sub writeFile
1066{
7a7884ad 1067 my($filename, $fileinput) = @_;
a26c150d 1068
1069 #
1070 # test for a valid $filename
1071 #
1072
1073 if ( !defined($filename) || (length($filename) lt 1) )
1074 {
74d5d582 1075 exitDie "Filename is undefined";
a26c150d 1076 }
1077
7a7884ad 1078 #
1079 # verify that we are prepared to work with $filename
1080 #
1081
1082 if ( !prepareFileWrite($filename) )
a26c150d 1083 {
7a7884ad 1084 return;
a26c150d 1085 }
1086
1087 #
1088 # write the output to $filename
1089 #
1090
1091 open(OUT, ">$filename");
1092 print OUT "$fileinput";
1093 close(OUT);
1094}
1095
7a7884ad 1096### action( $command )
ac083f7a 1097#
7a7884ad 1098# run $command within a proper system() command.
ac083f7a 1099#
1100
1101sub action
1102{
7a7884ad 1103 my($command) = @_;
ac083f7a 1104
1105 printf "$command\n";
1106
8b73e3d0 1107 my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1");
ac083f7a 1108
1109 if (($result or $?) and $command !~ m!patch!)
1110 {
74d5d582 1111 exitDie "ERROR: Unable to execute command: $!\n";
ac083f7a 1112 }
1113}
1114
74d5d582 1115### exitDie( $error )
1116#
1117# a horribly named method meant to look like die but only exit, thereby not causing
1118# gpt-postinstall to croak.
1119#
1120
1121sub exitDie
1122{
1123 my($error) = @_;
1124
1125 print $error;
1126 exit;
1127}
1128
7a7884ad 1129### query_boolean( $query_text, $default )
1130#
1131# query the user with a string, and expect a response. If the user hits
1132# 'enter' instead of entering an input, then accept the default response.
1133#
1134
ac083f7a 1135sub query_boolean
1136{
7a7884ad 1137 my($query_text, $default) = @_;
1138 my($nondefault, $foo, $bar);
ac083f7a 1139
bf1ee591 1140 if ( !$prompt )
571ab952 1141 {
1142 print "Prompt suppressed. Continuing...\n";
1143 return "y";
1144 }
1145
ac083f7a 1146 #
1147 # Set $nondefault to the boolean opposite of $default.
1148 #
1149
1150 if ($default eq "n")
1151 {
1152 $nondefault = "y";
1153 }
1154 else
1155 {
1156 $nondefault = "n";
1157 }
1158
1159 print "${query_text} ";
1160 print "[$default] ";
1161
e9ec5455 1162 $foo = <STDIN>;
1163 ($bar) = split //, $foo;
1164
e9d69a89 1165 if ( grep(/\s/, $bar) )
ac083f7a 1166 {
e9d69a89 1167 # this is debatable. all whitespace means 'default'
1168
1169 $bar = $default;
1170 }
be47d94e 1171 elsif ($bar eq '')
1172 {
1173 $bar = $default;
1174 }
e9d69a89 1175 elsif ($bar ne $default)
1176 {
1177 # everything else means 'nondefault'.
1178
1179 $bar = $nondefault;
1180 }
1181 else
1182 {
1183 # extraneous step. to get here, $bar should be eq to $default anyway.
1184
e9ec5455 1185 $bar = $default;
ac083f7a 1186 }
1187
e9ec5455 1188 return $bar;
ac083f7a 1189}
c096bf39 1190
1191### absolutePath( $file )
1192#
1193# converts a given pathname into a canonical path using the abs_path function.
1194#
1195
1196sub absolutePath
1197{
1198 my($file) = @_;
1199 my $home = $ENV{'HOME'};
1200 $file =~ s!~!$home!;
1201 my $startd = cwd();
1202 $file =~ s!^\./!$startd/!;
1203 $file = "$startd/$file" if $file !~ m!^\s*/!;
1204 $file = abs_path($file);
1205 return $file;
1206}
b48c75c0 1207
8c2b2cf1 1208### getOwnerID( $file )
1209#
1210# return the uid containing the owner ID of the given file.
1211#
1212
1213sub getOwnerID
1214{
1215 my($file) = @_;
1216 my($uid);
1217
1218 #
1219 # call stat() to get the mode of the file
1220 #
1221
1222 $uid = (stat($file))[4];
1223
1224 return $uid;
1225}
1226
b48c75c0 1227### getMode( $file )
1228#
1229# return a string containing the mode of the given file.
1230#
1231
1232sub getMode
1233{
1234 my($file) = @_;
1235 my($tempmode, $mode);
1236
1237 #
1238 # call stat() to get the mode of the file
1239 #
1240
1241 $tempmode = (stat($file))[2];
1242 if (length($tempmode) < 1)
1243 {
1244 return "";
1245 }
1246
1247 #
1248 # call sprintf to format the mode into a UNIX-like string
1249 #
1250
1251 $mode = sprintf("%04o", $tempmode & 07777);
1252
1253 return $mode;
1254}
1255
1256### userExists( $username )
1257#
1258# given a username, return true if the user exists on the system. return false
1259# otherwise.
1260#
1261
1262sub userExists
1263{
1264 my($username) = @_;
1265 my($uid);
1266
1267 #
1268 # retrieve the userid of the user with the given username
1269 #
1270
1271 $uid = getpwnam($username);
1272
1273 #
1274 # return true if $uid is defined and has a length greater than 0
1275 #
1276
1277 if ( defined($uid) and (length($uid) > 0) )
1278 {
1279 return 1;
1280 }
1281 else
1282 {
1283 return 0;
1284 }
1285}
This page took 0.274093 seconds and 5 git commands to generate.