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