]> andersk Git - gssapi-openssh.git/blame - setup/setup-openssh.pl
o Remove the two config file man pages from the setup package.
[gssapi-openssh.git] / setup / setup-openssh.pl
CommitLineData
7a7884ad 1#!/usr/bin/perl
20d3226a 2#
5002372c 3# setup-openssh.pl
4#
95f536ac 5# Adapts the installed gsi-openssh environment to the current machine,
5002372c 6# performing actions that originally occurred during the package's
7# 'make install' phase.
701aa556 8#
1eab725d 9# Send comments/fixes/suggestions to:
10# Chase Phillips <cphillip@ncsa.uiuc.edu>
701aa556 11#
20d3226a 12
7e12c9a7 13#
14# Get user's GPT_LOCATION since we may be installing this using a new(er)
15# version of GPT.
16#
17
18$gptpath = $ENV{GPT_LOCATION};
19
20#
21# And the old standby..
22#
23
4f276ad7 24$gpath = $ENV{GLOBUS_LOCATION};
ad71c979 25if (!defined($gpath))
26{
53a54c67 27 die "GLOBUS_LOCATION needs to be set before running this script"
ad71c979 28}
29
7a7884ad 30#
31# Include standard modules
32#
33
34use Getopt::Long;
35use Cwd;
36use Cwd 'abs_path';
37
8b73e3d0 38#
39# modify the ld library path for when we call ssh executables
40#
41
42$oldldpath = $ENV{LD_LIBRARY_PATH};
43$newldpath = "$gpath/lib";
44if (length($oldldpath) > 0)
45{
46 $newldpath .= ":$oldldpath";
47}
48$ENV{LD_LIBRARY_PATH} = "$newldpath";
49
ad71c979 50#
51# i'm including this because other perl scripts in the gpt setup directories
52# do so
53#
54
7e12c9a7 55if (defined($gptpath))
56{
57 @INC = (@INC, "$gptpath/lib/perl", "$gpath/lib/perl");
58}
59else
60{
61 @INC = (@INC, "$gpath/lib/perl");
62}
ad71c979 63
4f276ad7 64require Grid::GPT::Setup;
65
7a7884ad 66#
67# script-centred variable initialization
68#
69
ad71c979 70my $globusdir = $gpath;
ad71c979 71my $myname = "setup-openssh.pl";
72
20d3226a 73#
74# Set up path prefixes for use in the path translations
75#
76
d0a1bda7 77$prefix = ${globusdir};
78$exec_prefix = "${prefix}";
79$bindir = "${exec_prefix}/bin";
9cc10d0e 80$sbindir = "${exec_prefix}/sbin";
95f536ac 81$sysconfdir = "$prefix/etc/ssh";
82$localsshdir = "/etc/ssh";
20bb6dc8 83$setupdir = "$prefix/setup/gsi_openssh_setup";
e9ec5455 84
7a7884ad 85#
86# standard key types and their root file name mappings
87#
88
95f536ac 89my $keyfiles = {
90 "dsa" => "ssh_host_dsa_key",
91 "rsa" => "ssh_host_rsa_key",
92 "rsa1" => "ssh_host_key",
93 };
823981ba 94
7a7884ad 95#
96# argument specification. we offload some processing work from later functions
97# to verify correct args by using anon subs in various places.
98#
99
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
147 exit 0;
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";
bf1ee591 222print " <http://www.ncsa.uiuc.edu/Divisions/NSM/GST/GSI/openssh/>\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
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
4f3224f2 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
95f536ac 670sub determineKeys
823981ba 671{
95f536ac 672 my($keyhash, $keylist);
673 my($count);
823981ba 674
712b003f 675 #
676 # initialize our variables
677 #
678
95f536ac 679 $count = 0;
823981ba 680
95f536ac 681 $keyhash = {};
682 $keyhash->{gen} = []; # a list of keytypes to generate
683 $keyhash->{copy} = []; # a list of files to copy from the
712b003f 684
95f536ac 685 $genlist = $keyhash->{gen};
686 $copylist = $keyhash->{copy};
e9ec5455 687
712b003f 688 #
689 # loop over our keytypes and determine what we need to do for each of them
690 #
691
95f536ac 692 for my $keytype (keys %$keyfiles)
1a1f62a4 693 {
95f536ac 694 $basekeyfile = $keyfiles->{$keytype};
1a1f62a4 695
712b003f 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) )
95f536ac 704 {
7a7884ad 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 }
95f536ac 717 }
1a1f62a4 718
712b003f 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) )
95f536ac 728 {
712b003f 729 push(@$copylist, $basekeyfile);
95f536ac 730 $count++;
712b003f 731 next;
95f536ac 732 }
712b003f 733
734 #
735 # otherwise, we need to generate the key
736 #
737
738 push(@$genlist, $keytype);
739 $count++;
1a1f62a4 740 }
741
95f536ac 742 return $keyhash;
743}
744
4f3224f2 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
95f536ac 751sub runKeyGen
752{
753 my($gen_keys) = @_;
ce935927 754 my $keygen = "$bindir/ssh-keygen";
95f536ac 755
ce935927 756 if (@$gen_keys && -x $keygen)
1a1f62a4 757 {
712b003f 758 print "Generating ssh host keys...\n";
759
760 for my $k (@$gen_keys)
761 {
762 $keyfile = $keyfiles->{$k};
95f536ac 763
7a7884ad 764 if ( !isPresent("$sysconfdir/$keyfile") )
765 {
766 action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\"");
767 }
712b003f 768 }
1a1f62a4 769 }
770
771 return 0;
772}
773
7a7884ad 774### copySSHDConfigFile( )
5b105785 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
7a7884ad 780sub copySSHDConfigFile
20d3226a 781{
5b105785 782 my($fileInput, $fileOutput);
783 my($mode, $uid, $gid);
784 my($line, $newline);
b48c75c0 785 my($privsep_enabled);
823981ba 786
5b105785 787 print "Fixing paths in sshd_config...\n";
95f536ac 788
5b105785 789 $fileInput = "$setupdir/sshd_config.in";
790 $fileOutput = "$sysconfdir/sshd_config";
95f536ac 791
7a7884ad 792 #
793 # verify that we are prepared to work with $fileInput
794 #
795
796 if ( !isReadable($fileInput) )
95f536ac 797 {
7a7884ad 798 printf("Cannot read $fileInput... skipping.\n");
799 return;
5b105785 800 }
801
7a7884ad 802 #
803 # verify that we are prepared to work with $fileOuput
804 #
805
806 if ( !prepareFileWrite($fileOutput) )
5b105785 807 {
7a7884ad 808 return;
95f536ac 809 }
e9ec5455 810
b48c75c0 811 #
812 # check to see whether we should enable privilege separation
813 #
814
8c2b2cf1 815 if ( userExists("sshd") && ( -d "/var/empty" ) && ( getOwnerID("/var/empty") eq 0 ) )
b48c75c0 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
20d3226a 833 #
95f536ac 834 # Grab the current mode/uid/gid for use later
20d3226a 835 #
836
5b105785 837 $mode = (stat($fileInput))[2];
838 $uid = (stat($fileInput))[4];
839 $gid = (stat($fileInput))[5];
20d3226a 840
20d3226a 841 #
5b105785 842 # Open the files for reading and writing, and loop over the input's contents
20d3226a 843 #
844
b48c75c0 845 $data = readFile($fileInput);
20d3226a 846
b48c75c0 847 #
848 # alter the PidFile config
849 #
6193a4af 850
b48c75c0 851 $text = "PidFile\t$gpath/var/sshd.pid";
852 $data =~ s:^[\s|#]*PidFile.*$:$text:gm;
eb4172f6 853
b48c75c0 854 #
855 # set the sftp directive
856 #
7c96a399 857
b84327f8 858 $text = "Subsystem\tsftp\t$gpath/libexec/sftp-server";
b48c75c0 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);
7c96a399 873
95f536ac 874 #
875 # An attempt to revert the new file back to the original file's
876 # mode/uid/gid
877 #
7e12c9a7 878
5b105785 879 chmod($mode, $fileOutput);
880 chown($uid, $gid, $fileOutput);
20d3226a 881
882 return 0;
883}
884
b48c75c0 885### setPrivilegeSeparation( $value )
886#
887# set the privilege separation variable to $value
888#
889
890sub 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
902sub getPrivilegeSeparation
903{
904 return $privsep;
905}
906
7a7884ad 907### prepareFileWrite( $file )
908#
909# test $file to prepare for writing to it.
910#
911
912sub 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
5b105785 944### copyConfigFiles( )
945#
946# subroutine that copies some extra config files to their proper location in
947# $GLOBUS_LOCATION/etc/ssh.
948#
949
950sub copyConfigFiles
951{
7a7884ad 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");
5b105785 967
7a7884ad 968 #
969 # copy and alter the SXXsshd script.
970 #
971
972 copySXXScript("$setupdir/SXXsshd.in", "$sbindir/SXXsshd");
5b105785 973}
974
7a7884ad 975### copyFile( $src, $dest )
4f3224f2 976#
7a7884ad 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.
4f3224f2 979#
980
7a7884ad 981sub copyFile
a26c150d 982{
7a7884ad 983 my($src, $dest) = @_;
d58b3a33 984
7a7884ad 985 if ( !isReadable($src) )
20bb6dc8 986 {
7a7884ad 987 printf("$src is not readable... not creating $dest.\n");
988 return;
20bb6dc8 989 }
7a7884ad 990
991 if ( !prepareFileWrite($dest) )
992 {
993 return;
994 }
995
996 action("cp $src $dest");
d58b3a33 997}
998
7a7884ad 999### copySXXScript( $in, $out )
4f3224f2 1000#
7a7884ad 1001# parse the input file, substituting in place the value of GLOBUS_LOCATION, and
1002# write the result to the output file.
4f3224f2 1003#
1004
7a7884ad 1005sub copySXXScript
d58b3a33 1006{
7a7884ad 1007 my($in, $out) = @_;
b1282c82 1008 my($tmpgpath);
7a7884ad 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
b1282c82 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
7a7884ad 1033 $data = readFile($in);
b1282c82 1034 $data =~ s|\@GLOBUS_LOCATION\@|$tmpgpath|g;
7a7884ad 1035 writeFile($out, $data);
1036 action("chmod 755 $out");
a26c150d 1037}
1038
1039### readFile( $filename )
1040#
1041# reads and returns $filename's contents
1042#
1043
1044sub readFile
1045{
7a7884ad 1046 my($filename) = @_;
1047 my($data);
a26c150d 1048
7a7884ad 1049 open(IN, "$filename") || die "Can't open '$filename': $!";
a26c150d 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
1064sub writeFile
1065{
7a7884ad 1066 my($filename, $fileinput) = @_;
a26c150d 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
7a7884ad 1077 #
1078 # verify that we are prepared to work with $filename
1079 #
1080
1081 if ( !prepareFileWrite($filename) )
a26c150d 1082 {
7a7884ad 1083 return;
a26c150d 1084 }
1085
1086 #
1087 # write the output to $filename
1088 #
1089
1090 open(OUT, ">$filename");
1091 print OUT "$fileinput";
1092 close(OUT);
1093}
1094
7a7884ad 1095### action( $command )
ac083f7a 1096#
7a7884ad 1097# run $command within a proper system() command.
ac083f7a 1098#
1099
1100sub action
1101{
7a7884ad 1102 my($command) = @_;
ac083f7a 1103
1104 printf "$command\n";
1105
8b73e3d0 1106 my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1");
ac083f7a 1107
1108 if (($result or $?) and $command !~ m!patch!)
1109 {
1110 die "ERROR: Unable to execute command: $!\n";
1111 }
1112}
1113
7a7884ad 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
ac083f7a 1120sub query_boolean
1121{
7a7884ad 1122 my($query_text, $default) = @_;
1123 my($nondefault, $foo, $bar);
ac083f7a 1124
bf1ee591 1125 if ( !$prompt )
571ab952 1126 {
1127 print "Prompt suppressed. Continuing...\n";
1128 return "y";
1129 }
1130
ac083f7a 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
e9ec5455 1147 $foo = <STDIN>;
1148 ($bar) = split //, $foo;
1149
e9d69a89 1150 if ( grep(/\s/, $bar) )
ac083f7a 1151 {
e9d69a89 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
e9ec5455 1166 $bar = $default;
ac083f7a 1167 }
1168
e9ec5455 1169 return $bar;
ac083f7a 1170}
c096bf39 1171
1172### absolutePath( $file )
1173#
1174# converts a given pathname into a canonical path using the abs_path function.
1175#
1176
1177sub 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}
b48c75c0 1188
8c2b2cf1 1189### getOwnerID( $file )
1190#
1191# return the uid containing the owner ID of the given file.
1192#
1193
1194sub 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
b48c75c0 1208### getMode( $file )
1209#
1210# return a string containing the mode of the given file.
1211#
1212
1213sub 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
1243sub 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.491514 seconds and 5 git commands to generate.