3 # Compile server client for systemtap
5 # Copyright (C) 2008, 2009 Red Hat Inc.
7 # This file is part of systemtap, and is free software. You can
8 # redistribute it and/or modify it under the terms of the GNU General
9 # Public License (GPL); either version 2, or (at your option) any
12 # This script examines the systemtap command line and packages the files and
13 # information needed to execute the command. This is then sent to a trusted
14 # systemtap server which will process the request and return the resulting
15 # kernel module (if requested) and any other information generated by the
16 # request. If a kernel module is generated, this script will load the module
17 # and execute it using 'staprun', if requested.
19 # Catch ctrl-c and other termination signals
20 trap 'terminate' SIGTERM
21 trap 'interrupt' SIGINT
22 trap 'ignore_signal' SIGHUP SIGPIPE
24 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # function: configuration
28 function configuration
{
29 # INSTALL-HOOK These settings work for running the client from the source tree
30 # INSTALL-HOOK using the dejagnu test harness and will be overridden at install
35 # General configuration
36 tmpdir_prefix_client
=stap.client
37 tmpdir_prefix_server
=stap.server
38 avahi_service_tag
=_stap._tcp
41 # function: initialization
42 function initialization
{
43 our_host_name
=`expr "$HOSTNAME" : "\\\([a-zA-Z0-9-]*\\\).*"`
44 our_domain_name
=`expr "$HOSTNAME" : "$our_host_name\\\(.*\\\)"`
51 # Default location for server certificates if we're not root
52 # Must be owned by us.
54 if test $EUID != 0; then
55 if test -e $HOME/.systemtap
/ssl
/client
; then
56 if check_db
$HOME/.systemtap
/ssl
/client
$EUID $USER; then
57 local_ssl_dbs
=$HOME/.systemtap
/ssl
/client
61 # Additional location for all users. Must be owned by root.
62 if test "X$sysconfdir" != "X"; then
63 if test -e $sysconfdir/systemtap
/ssl
/client
; then
64 if check_db
$sysconfdir/systemtap
/ssl
/client
0 root
; then
65 public_ssl_dbs
=$sysconfdir/systemtap
/ssl
/client
70 # Default options settings
76 # Default variable settings
79 # Create a temporary directory to package things in
80 # Do this before parsing the command line so that there is a place
81 # to put -I and -R directories.
82 tmpdir_client
=`mktemp -dt $tmpdir_prefix_client.XXXXXX` || \
83 fatal
"Cannot create temporary directory " $tmpdir_client
84 tmpdir_env
=`dirname $tmpdir_client`
87 # function: parse_options [ STAP-OPTIONS ]
89 # Examine the command line. We need not do much checking, but we do need to
90 # parse all options in order to discover the ones we're interested in.
91 # The server will take care of most situations and return the appropriate
94 function parse_options
{
103 # Start of a new token.
105 until test $advance_p != 0
107 # Identify the next option
108 first_char
=`expr "$first_token" : '\(.\).*'`
110 if test $dash_seen = 0; then
111 if test "$first_char" = "-"; then
112 if test "$first_token" != "-"; then
113 # It's not a lone dash, so it's an option.
114 # Is it a long option (i.e. --option)?
115 second_char
=`expr "$first_token" : '.\(.\).*'`
116 if test "X$second_char" = "X-"; then
117 long_option
=`expr "$first_token" : '--\(.*\)=.*'`
118 test "X$long_option" != "X" || long_option
=`expr "$first_token" : '--\(.*\)'`
121 process_ssl
$first_token
124 process_server
$first_token
127 # An unknown or unimportant option.
128 # Ignore it, but pass it on to the server.
129 cmdline2
="$cmdline2 $first_token"
132 advance_p
=$
(($advance_p + 1))
135 # It's not a lone dash, or a long option, so it's a short option string.
137 first_token
=`expr "$first_token" : '-\(.*\)'`
139 first_char
=`expr "$first_token" : '\(.\).*'`
140 cmdline2
="$cmdline2 -"
143 if test $dash_seen = 0; then
144 # The dash has not been seen. This is either the script file
145 # name, a long argument or an argument to be passed to the probe module.
146 # If this is the first time, and -e has not been specified,
147 # then it could be the name of the script file.
148 if test "X$second_char" = "X-"; then
149 cmdline2
="$cmdline2 $first_token"
150 elif test "X$e_script" = "X" -a "X$script_file" = "X"; then
151 script_file
=$first_token
154 elif test "$first_char" != "'"; then
155 cmdline2
="$cmdline2 '$first_token'"
157 cmdline2
="$cmdline2 $first_token"
159 advance_p
=$
(($advance_p + 1))
164 # We are at the start of an option. Look at the first character.
170 get_arg
$first_token "$2"
171 process_c
"$stap_arg"
174 get_arg
$first_token $2
175 cmdline2
="${cmdline2}D '$stap_arg'"
178 get_arg
$first_token "$2"
179 process_e
"$stap_arg"
182 get_arg
$first_token $2
189 get_arg
$first_token $2
190 cmdline2
="${cmdline2}l '$stap_arg'"
193 get_arg
$first_token $2
197 get_arg
$first_token $2
201 get_arg
$first_token $2
205 get_arg
$first_token $2
206 cmdline2
="${cmdline2}r '$stap_arg'"
209 get_arg
$first_token $2
213 get_arg
$first_token $2
214 cmdline2
="${cmdline2}s '$stap_arg'"
217 v_level
=$
(($v_level + 1))
220 get_arg
$first_token $2
221 cmdline2
="${cmdline2}x '$stap_arg'"
224 # An unknown or unimportant flag. Ignore it, but pass it on to the server.
228 if test $advance_p = 0; then
229 # Just another flag character. Consume it.
230 cmdline2
="$cmdline2$first_char"
231 first_token
=`expr "$first_token" : '.\(.*\)'`
232 if test "X$first_token" = "X"; then
233 advance_p
=$
(($advance_p + 1))
238 # Consume the arguments we just processed.
239 while test $advance_p != 0
242 advance_p
=$
(($advance_p - 1))
246 # If the script file was given and it's not '-', then replace it with its
247 # client-temp-name in the command string.
248 if test "X$script_file" != "X"; then
250 if test "$script_file" != "-"; then
251 local_name
=`generate_client_temp_name $script_file`
253 local_name
=$script_file
255 cmdline
="$cmdline1 script/$local_name $cmdline2"
257 cmdline
="$cmdline1 $cmdline2"
260 # Processing based on final options settings
261 # Complete the list of local certificate databases
262 local_ssl_dbs
="$additional_local_ssl_dbs $local_ssl_dbs"
264 # We must have at least one usable certificate database.
265 test "X$local_ssl_dbs" != "X " -o "X$public_ssl_dbs" != "X" || \
266 fatal
"No usable certificate databases found"
268 # We can use any server if the phase is less than 5
269 if test $p_phase -lt 5; then
274 # function: get_arg FIRSTWORD SECONDWORD
276 # Collect an argument to the given option
278 # Remove first character.
279 local opt
=`expr "$1" : '\(.\).*'`
280 local first
=`expr "$1" : '.\(.*\)'`
282 # Advance to the next token, if the first one is exhausted.
283 if test "X$first" = "X"; then
285 advance_p
=$
(($advance_p + 1))
289 test "X$first" != "X" || \
290 fatal
"Missing argument to -$opt"
293 advance_p
=$
(($advance_p + 1))
296 # function: process_ssl ARGUMENT
298 # Process the --ssl option.
299 function process_ssl
{
300 local db
=`expr "$1" : '--ssl=\(.*\)'`
302 test "X$db" != "X" || \
303 fatal
"Missing argument to --ssl"
305 check_db
$db ||
return
307 additional_local_ssl_dbs
="$additional_local_ssl_dbs $db"
310 # function: process_server ARGUMENT
312 # Process the --server option.
313 function process_server
{
314 local spec
=`expr "$1" : '--server=\(.*\)'`
316 test "X$spec" != "X" || \
317 fatal
"Missing argument to --server"
319 specified_servers
="$specified_servers $spec"
322 # function: process_c ARGUMENT
324 # Process the -c flag.
327 cmdline2
="${cmdline2}c '$1'"
330 # function: process_e ARGUMENT
332 # Process the -e flag.
334 # Only the first -e option is recognized and it overrides any script file name
335 # which may have already been identified.
336 if test "X$e_script" = "X"; then
338 if test "X$script_file" != "X"; then
339 cmdline1
="$cmdline1 $script_file $cmdline2"
344 cmdline2
="${cmdline2}e '$1'"
347 # function: process_I ARGUMENT
349 # Process the -I flag.
351 local local_name
=`include_file_or_directory tapsets $1`
352 test "X$local_name" != "X" ||
return
353 cmdline2
="${cmdline2}I 'tapsets/$local_name'"
356 # function: process_m ARGUMENT
358 # Process the -m flag.
361 cmdline2
="${cmdline2}m '$1'"
364 # function: process_o ARGUMENT
366 # Process the -o flag.
368 stdout_redirection
="$1"
369 cmdline2
="${cmdline2}o '$1'"
372 # function: process_p ARGUMENT
374 # Process the -p flag.
377 cmdline2
="${cmdline2}p '$1'"
380 # function: process_R ARGUMENT
382 # Process the -R flag.
384 local local_name
=`include_file_or_directory runtime $1`
385 test "X$local_name" != "X" ||
return
386 cmdline2
="${cmdline2}R 'runtime/$local_name'"
389 # function: include_file_or_directory PREFIX NAME
391 # Include the given file or directory in the client's temporary
392 # tree to be sent to the server.
393 function include_file_or_directory
{
394 # Add a symbolic link of the named file or directory to our temporary directory
395 local local_name
=`generate_client_temp_name $2`
396 mkdir
-p $tmpdir_client/$1/`dirname $local_name` || \
397 fatal
"Could not create $tmpdir_client/$1/`dirname $local_name`"
398 ln -s /$local_name $tmpdir_client/$1/$local_name || \
399 fatal
"Could not link $tmpdir_client/$1/$local_name to /$local_name"
403 # function: generate_client_temp_name NAME
405 # Generate the name to be used for the given file/directory relative to the
406 # client's temporary directory.
407 function generate_client_temp_name
{
408 # Transform the name into a fully qualified path name
409 local full_name
=`echo "$1" | sed "s,^\\\([^/]\\\),$wd/\\\\1,"`
411 # The same name without the initial / or trailing /
412 local local_name
=`echo "$full_name" | sed 's,^/\(.*\),\1,'`
413 local_name
=`echo "$local_name" | sed 's,\(.*\)/$,\1,'`
417 # function: create_request
419 # Add information to the client's temp directory representing the request
421 function create_request
{
422 # Work in our temporary directory
425 if test "X$script_file" != "X"; then
426 if test "$script_file" = "-"; then
427 mkdir
-p $tmpdir_client/script || \
428 fatal
"Cannot create temporary directory " $tmpdir_client/script
429 cat > $tmpdir_client/script
/$script_file
431 include_file_or_directory
script $script_file > /dev
/null
435 # Add the necessary info to special files in our temporary directory.
436 echo "cmdline: $cmdline" > cmdline
437 echo "sysinfo: `client_sysinfo`" > sysinfo
440 # function client_sysinfo
442 # Generate the client's sysinfo and echo it to stdout
443 function client_sysinfo
{
444 if test "X$sysinfo_client" = "X"; then
445 # Add some info from uname
446 sysinfo_client
="`uname -rvm`"
448 echo "$sysinfo_client"
451 # function: package_request
453 # Package the client's temp directory into a form suitable for sending to the
455 function package_request
{
456 # Package up the temporary directory into a zip file
459 local tmpdir_client_base
=`basename $tmpdir_client`
460 zip_client
=$tmpdir_env/`mktemp $tmpdir_client_base.zip.XXXXXX` || \
461 fatal
"Cannot create temporary file " $zip_client
463 (rm $zip_client && zip -r $zip_client $tmpdir_client_base > /dev
/null
) || \
464 fatal
"zip of request tree, $tmpdir_client, failed"
467 # function: unpack_response
469 # Unpack the zip file received from the server and make the contents available
470 # for printing the results and/or running 'staprun'.
471 function unpack_response
{
472 tmpdir_server
=`mktemp -dt $tmpdir_prefix_client.server.XXXXXX` || \
473 fatal
"Cannot create temporary file " $tmpdir_server
475 # Unpack the server output directory
476 unzip -d $tmpdir_server $zip_server > /dev
/null || \
477 fatal
"Cannot unpack server response, $zip_server"
479 # Check the contents of the expanded directory. It should contain a
480 # single directory whose name matches stap.server.??????
481 local num_files
=`ls $tmpdir_server | wc -l`
482 test $num_files = 1 || \
483 fatal
"Wrong number of files in server's temp directory"
484 test -d $tmpdir_server/stap.server.?????? || \
485 fatal
"`ls $tmpdir_server` does not match the expected name or is not a directory"
486 # Move the contents of the directory down one level.
487 mv $tmpdir_server/stap.server.??????
/* $tmpdir_server
488 rm -fr $tmpdir_server/stap.server.??????
490 # Check the contents of the directory. It should contain:
491 # 1) a file called stdout
492 # 2) a file called stderr
493 # 3) a file called rc
494 # 4) optionally a directory named to match stap??????
495 num_files
=`ls $tmpdir_server | wc -l`
496 test $num_files = 4 -o $num_files = 3 || \
497 fatal
"Wrong number of files in server's temp directory"
498 test -f $tmpdir_server/stdout || \
499 fatal
"`pwd`/$tmpdir_server/stdout does not exist or is not a regular file"
500 test -f $tmpdir_server/stderr || \
501 fatal
"`pwd`/$tmpdir_server/stderr does not exist or is not a regular file"
502 test -f $tmpdir_server/rc || \
503 fatal
"`pwd`/$tmpdir_server/rc does not exist or is not a regular file"
505 # See if there is a systemtap temp directory
506 tmpdir_stap
=`cd $tmpdir_server && ls | grep stap......\$ 2>/dev/null`
507 if test "X$tmpdir_stap" != "X"; then
508 test -d $tmpdir_server/$tmpdir_stap || \
509 fatal
"$tmpdir_server/$tmpdir_stap is not a directory"
511 # Move the systemtap temp directory to a local temp location, if -k
513 if test $keep_temps = 1; then
514 local local_tmpdir_stap
=`mktemp -dt stapXXXXXX` || \
515 fatal
"Cannot create temporary directory " $local_tmpdir_stap
516 mv $tmpdir_server/$tmpdir_stap/* $local_tmpdir_stap 2>/dev
/null
517 rm -fr $tmpdir_server/$tmpdir_stap
519 # Correct the name of the temp directory in the server's stderr output
520 sed -i "s,^Keeping temporary directory.*,Keeping temporary directory \"$local_tmpdir_stap\"," $tmpdir_server/stderr
521 tmpdir_stap
=$local_tmpdir_stap
523 # Make sure we own the systemtap temp directory if we are root.
524 test $EUID = 0 && chown
$EUID:$EUID $tmpdir_server/$tmpdir_stap
529 # function: find_and_connect_to_server
531 # Find and establish connection with a compatible stap server.
532 function find_and_connect_to_server
{
535 # Make a place to receive the response file.
536 zip_server
=`mktemp -t $tmpdir_prefix_client.server.zip.XXXXXX` || \
537 fatal
"Cannot create temporary file " $zip_server
539 # Make a place to record connection errors
540 touch $tmpdir_client/connect
542 # If servers were specified on the command line, then try them
543 # in sequence. Don't try any other servers.
544 if test "X$specified_servers" != "X"; then
545 for server
in $specified_servers; do
546 num_servers
=$
(($num_servers + 1))
548 # If the server is completely specified, (i.e. server:port),
549 # then try it directly.
550 port
=`expr "$server" : '.\+:\([0-9]\+\)'`
551 if test "X$port" != "X"; then
552 name
=`expr "$server" : '\(.\+\):[0-9]\+'`
554 # If we have been given an ip address, then try to resolve it to a name.
555 # If we have been given a name, try to resolve the full name.
556 # The full name is needed in order to validate the server's certificate.
557 address
=`expr "$name" : '\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)'`
558 if test "X$address" = "X"; then
559 # We've been given a host name
560 full_name
=`nslookup $name | awk '/^Name\:/ {print $2}'`
561 if test "X$full_name" != "X"; then
565 # We've been given an ip address.
566 name
=`nslookup $address | awk '/in-addr\.arpa/ {print $4}'`
567 name
=`expr "$name" : '\(.*\)\.'`
568 if test "X$name" = "X"; then
569 echo "Cannot resolve ip address $address" >> $tmpdir_client/connect
574 # Now try to contact the given server.
575 ssl_db
=`send_receive $name $port`
576 test "X$ssl_db" != "X" && return
580 # Otherwise select the matching server from the available servers
581 # and use the port it is advertizing.
583 # Have we been given an ip address? If so, just use it.
584 address
=`expr "$server" : '\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)'`
585 if test "X$address" = "X"; then
586 # We have not been given an ip address. Try to resolve it as a host name.
587 if test "X$server" = "Xlocalhost"; then
588 # We don't want the address of the loopback interface here. Avahi will present
589 # the actual ip address.
590 server
=$our_host_name$our_domain_name
592 address
=`nslookup $server | awk '/^Address\:[ \t][0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ {print $2}'`
593 if test "X$address" = "X"; then
594 echo "Cannot resolve server $server" >> $tmpdir_client/connect
599 if test `${exec_prefix}stap-find-servers $find_all | grep $address | wc -l` = "0"; then
600 warning
"No server is available on $server" 2>> $tmpdir_client/connect
604 ssl_db
=`${exec_prefix}stap-find-servers $find_all | grep $address | choose_server`
605 test "X$ssl_db" != "X" && return
608 # No servers specified. Find available servers and choose one of them.
609 # Remember which ssl certificate database was used to authenticate the chosen
611 ssl_db
=`${exec_prefix}stap-find-servers $find_all | choose_server`
612 test "X$ssl_db" != "X" && return
614 num_servers
=`${exec_prefix}stap-find-servers $find_all | wc -l`
617 if test $num_servers = 0; then
618 fatal
"Unable to find a server"
621 cat $tmpdir_client/connect
>&2
622 fatal
"Unable to connect to a server"
625 # function: choose_server
627 # Examine each line from stdin and attempt to connect to each server
628 # specified until successful.
629 # echo the name of the ssl certificate database used to successfully authenticate
631 function choose_server
{
632 local name ip port remain
634 while read name ip port remain
636 if test "X$name" = "X"; then
637 fatal
"Server name not provided by avahi"
640 # if test "X$ip" = "X"; then
641 # fatal "Server ip address not provided by avahi"
644 if test "X$port" = "X"; then
645 fatal
"Server port not provided by avahi"
648 ssl_db
=`send_receive $name $port`
649 test "X$ssl_db" != "X" && echo $ssl_db && return
653 # function: send_receive SERVER PORT
655 # Connect to the server, send the request and receive the response
656 # echo the name of the ssl certificate database used to successfully authenticate
658 function send_receive
{
662 # The server must match the dns name on the certificate
663 # and must be 'localhost' if the server is on the local host.
664 local server_host_name
=`expr "$server" : "\\\([a-zA-Z0-9-]*\\\).*"`
665 local server_domain_name
=`expr "$server" : "$server_host_name\\\(.*\\\)"`
667 if test "X$server_domain_name" = "X.local"; then
668 server_domain_name
=$our_domain_name
670 if test "X$server_host_name$server_domain_name" = "Xlocalhost$our_domain_name"; then
672 elif test "X$server_host_name$server_domain_name" = "X$our_host_name$our_domain_name"; then
675 server
=$server_host_name$server_domain_name
678 # Try to connect using each of the given local certificate databases in turn
680 for db
in $local_ssl_dbs
682 # Send the request and receive the response using stap-client-connect
683 echo "Attempting connection with $server:$port using certificate database in '$db'" >> $tmpdir_client/connect
684 ${exec_prefix}stap-client-connect
-i $zip_client -o $zip_server -d $db -p $port -h $server >> $tmpdir_client/connect
2>&1 &
685 wait '%${exec_prefix}stap-client-connect'
686 test $?
= 0 && echo $db && return
690 # Next, try the public certificate databases.
691 for db
in $public_ssl_dbs
693 # Send the request and receive the response using stap-client-connect
694 echo "Attempting connection with $server:$port using certificate database in '$db'" >> $tmpdir_client/connect
695 ${exec_prefix}stap-client-connect
-i $zip_client -o $zip_server -d $db -p $port -h $server >> $tmpdir_client/connect
2>&1 &
696 wait '%${exec_prefix}stap-client-connect'
697 test $?
= 0 && echo $db && return
701 # Could not connect using any of the certificate databases
704 # function: process_response
706 # Write the stdout and stderr from the server to stdout and stderr respectively.
707 function process_response
{
708 # Pick up the results of running stap on the server.
712 # Copy the module to the current directory, if -m was specified
713 if test "X$m_name" != "X"; then
714 if test -f $tmpdir_stap/$m_name.ko
; then
715 cp $tmpdir_stap/$m_name.ko
$wd
718 fatal
"module $tmpdir_stap/$m_name.ko does not exist"
722 # Output stdout and stderr as directed
726 # function: stream_output
728 # Output stdout and stderr as directed
729 function stream_output
{
735 # function: maybe_call_staprun
737 # Call staprun using the module returned from the server, if requested.
738 function maybe_call_staprun
{
739 if test $rc != 0; then
740 # stap run on the server failed, so don't bother
744 if test $p_phase -ge 4; then
745 # There should be a systemtap temporary directory.
746 if test "X$tmpdir_stap" = "X"; then
747 # OK if no script specified
748 if test "X$e_script" != "X" -o "X$script_file" != "X"; then
749 fatal
"systemtap temporary directory is missing in server response"
754 # There should be a module.
755 local mod_name
=`ls $tmpdir_stap | grep '.ko$'`
756 if test "X$mod_name" = "X"; then
757 fatal
"No module was found in $tmpdir_stap"
760 if test $p_phase = 5; then
761 test $v_level -gt 0 && echo "Pass 5: starting run." >&2
763 # We have a module. Try to run it
764 # If a -c command was specified, pass it along.
765 if test "X$c_cmd" != "X"; then
766 staprun_opts
="-c '$c_cmd'"
769 # The -v level will be one less than what was specified
771 for ((vl
=$
((v_level
- 1)); $vl > 0; --vl))
773 staprun_opts
="$staprun_opts -v"
776 # if -o was specified, pass it along
777 if test "X$stdout_redirection" != "X"; then
778 staprun_opts
="$staprun_opts -o $stdout_redirection"
781 # Run it in the background and wait for it. This
782 # way any signals send to us can be caught.
783 if test $v_level -ge 2; then
784 echo "running `which staprun` $staprun_opts $tmpdir_stap/`ls $tmpdir_stap | grep '.ko$'`" >&2
786 eval `staprun_PATH` "$staprun_opts" \
787 $tmpdir_stap/`ls $tmpdir_stap | grep '.ko$'`
789 wait '%?staprun' > /dev
/null
2>&1
792 # 127 from wait means that the job was already finished.
795 # Wait until the job actually disappears so that its output is complete.
796 while jobs '%?staprun' >/dev
/null
2>&1
801 test $v_level -gt 0 && echo "Pass 5: run completed in 0usr/0sys/0real ms." >&2
806 # function: staprun_PATH
808 # Compute a PATH suitable for running staprun.
809 function staprun_PATH
{
810 # If $SYSTEMTAP_STAPRUN is set, then use that
811 if test "X$SYSTEMTAP_STAPRUN" != "X"; then
812 echo $SYSTEMTAP_STAPRUN
816 # Otherwise, if there is an exec_prefix, then use it.
817 if test "X$exec_prefix" != "X"; then
818 echo ${exec_prefix}staprun
822 # Otherwise, we have been called by the dejagnu test harness as 'stap'
823 # and we are the first 'stap' on the path. Since staprun may call
824 # 'stap', remove the PATH component where we live from the PATH in order to
826 local first_stap
=`which stap`
827 local PATH_component
=`dirname $first_stap`
828 echo "PATH=$PATH staprun" |
sed "s,$PATH_component,,g"
831 # function: check_db DBNAME [ EUID USER ]
833 # Check the security of the given database directory.
840 # Check that we have been given a directory
841 if ! test -e $dir; then
842 warning
"Certificate database '$dir' does not exist"
845 if ! test -d $dir; then
846 warning
"Certificate database '$dir' is not a directory"
850 # If euid has been specified, then this directory must be owned by that
852 if test "X$euid" != "X"; then
853 local ownerid
=`stat -c "%u" $dir`
854 if test "X$ownerid" != "X$euid"; then
855 warning
"Certificate database '$dir' must be owned by $user"
860 # Check that we can read the directory
861 if ! test -r $dir; then
862 warning
"Certificate database '$dir' is not readble"
866 # Check the access permissions of the directory
867 local perm
=0`stat -c "%a" $dir`
868 if test $
((($perm & 0400) == 0400)) = 0; then
869 warning
"Certificate database '$dir' should be readable by the owner"
871 if test $
((($perm & 0200) == 0200)) = 0; then
872 warning
"Certificate database '$dir' should be writeable by the owner"
874 if test $
((($perm & 0100) == 0100)) = 0; then
875 warning
"Certificate database '$dir' should be searchable by the owner"
877 if test $
((($perm & 0040) == 0040)) = 0; then
878 warning
"Certificate database '$dir' should be readable by the group"
880 if test $
((($perm & 0020) == 0020)) = 1; then
881 warning
"Certificate database '$dir' must not be writable by the group"
884 if test $
((($perm & 0010) == 0010)) = 0; then
885 warning
"Certificate database '$dir' should be searchable by the group"
887 if test $
((($perm & 0004) == 0004)) = 0; then
888 warning
"Certificate database '$dir' should be readable by others"
890 if test $
((($perm & 0002) == 0002)) = 1; then
891 warning
"Certificate database '$dir' must not be writable by others"
894 if test $
((($perm & 0001) == 0001)) = 0; then
895 warning
"Certificate database '$dir' should be searchable by others"
898 # Now check the permissions of the critical files.
899 check_db_file
$dir/cert8.db
$euid $user || rc
=1
900 check_db_file
$dir/key3.db
$euid $user || rc
=1
901 check_db_file
$dir/secmod.db
$euid $user || rc
=1
903 test $rc = 1 && warning
"Unable to use certificate database '$dir' due to errors"
908 # function: check_db_file FILENAME [ EUID USER ]
910 # Check the security of the given database file.
911 function check_db_file
{
915 # Check that we have been given a file
916 if ! test -e $file; then
917 warning
"Certificate database file '$file' does not exist"
920 if ! test -f $file; then
921 warning
"Certificate database file '$file' is not a regular file"
925 # If euid has been specified, then this directory must be owned by that
927 if test "X$euid" != "X"; then
928 local ownerid
=`stat -c "%u" $file`
929 if test "X$ownerid" != "X$euid"; then
930 warning
"Certificate database file '$file' must be owned by $user"
935 # Check that we can read the file
936 if ! test -r $file; then
937 warning
"Certificate database file '$file' is not readble"
941 # Check the access permissions of the file
942 local perm
=0`stat -c "%a" $file`
943 if test $
((($perm & 0400) == 0400)) = 0; then
944 warning
"Certificate database file '$file' should be readable by the owner"
946 if test $
((($perm & 0200) == 0200)) = 0; then
947 warning
"Certificate database file '$file' should be writeable by the owner"
949 if test $
((($perm & 0100) == 0100)) = 1; then
950 warning
"Certificate database file '$file' must not be executable by the owner"
953 if test $
((($perm & 0040) == 0040)) = 0; then
954 warning
"Certificate database file '$file' should be readable by the group"
956 if test $
((($perm & 0020) == 0020)) = 1; then
957 warning
"Certificate database file '$file' must not be writable by the group"
960 if test $
((($perm & 0010) == 0010)) = 1; then
961 warning
"Certificate database file '$file' must not be executable by the group"
964 if test $
((($perm & 0004) == 0004)) = 0; then
965 warning
"Certificate database file '$file' should be readable by others"
967 if test $
((($perm & 0002) == 0002)) = 1; then
968 warning
"Certificate database file '$file' must not be writable by others"
971 if test $
((($perm & 0001) == 0001)) = 1; then
972 warning
"Certificate database file '$file' must not be executable by others"
979 # function: warning [ MESSAGE ]
982 # Prints its arguments to stderr
984 echo "$0: WARNING:" "$@" >&2
987 # function: fatal [ MESSAGE ]
990 # Prints its arguments to stderr and exits
992 echo "$0: ERROR:" "$@" >&2
999 # Cleanup work files unless asked to keep them.
1003 if test $keep_temps != 1; then
1004 rm -fr $tmpdir_client
1007 rm -fr $tmpdir_server
1011 # function: terminate
1013 # Terminate gracefully.
1014 function terminate
{
1016 echo "$0: terminated by signal" >&2
1019 # Kill any running staprun job
1020 kill -s SIGTERM
'%?staprun' 2>/dev
/null
1022 # Kill any stap-client-connect job
1023 kill -s SIGTERM
'%${exec_prefix}stap-client-connect' 2>/dev
/null
1028 # function: interrupt
1030 # Pass an interrupt (ctrl-C) to staprun
1031 function interrupt
{
1032 # Pass the signal on to any running staprun job
1033 if test $staprun_running = 1; then
1034 kill -s SIGINT
'%?staprun' 2>/dev
/null
1038 # Kill any stap-client-connect job
1039 # SIGINT won't do it.
1040 kill -s SIGTERM
'%${exec_prefix}stap-client-connect' 2>/dev
/null
1042 # If staprun was not running, then exit.
1047 # function: ignore_signal
1049 # Called in order to ignore a signal
1050 function ignore_signal
{
1054 #-----------------------------------------------------------------------------
1055 # Beginning of main line execution.
1056 #-----------------------------------------------------------------------------
1062 find_and_connect_to_server