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