blob: 23ba7a026898031f536a66ffccef3bbb7011269e [file]
#!/bin/bash
# @@@ START COPYRIGHT @@@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# @@@ END COPYRIGHT @@@
# -----------------------------------------------------------------------------
# script: krb5service
#
# This script manages the Kerberos ticket service for Trafodion
#
# The Kerberos ticket service consists of three scripts:
# - krb5service (this script) which manages the service
# - krb5check - wakes up periodically to log ticket status and renew tickets
# - krb5functions - contains common functions used by krb5service & krb5check
#
# (krb5check runs in an infinite loop which wakes up periodically to check to
# see if the Trafodion ticket is ready to expire. If ticket is ready to expire,
# it renews the existing ticket if retries are available. If no more retries
# are available, it reports the problem and continues. Ticket life times and
# renewal life times are based on the ticket defaults. The script periodically
# reports the ticket status to a log file.)
#
# Options:
# init - inits a new Trafodion ticket based on existing ticket attributes
# restart - stops then restarts the ticket renewal service
# start - starts the ticket renewal service
# status - displays the status of the Trafodion service ticket
# stop - stops the ticket renewal service
#
# Location attributes (see krb5functions to change these values):
# [LOG_FILE] : $TRAF_HOME/logs/krb5check - log where all events are stored
# (the log file is recreated each time the krb5service is started)
# [LOCK_FILE] : $TRAF_VAR/krb5check - file to keep track of krb5check process
# (acts as a semiphore to prevent multiple occurrances from running)
# [CACHE_FILE]: /tmp/krb5cc_(trafodion linux UID) - default location for Kerberos
# cache ticket store (CACHE_FILE)
# [KEYTAB]: /etc/security/keytabs/trafodion.service.keytab - location where trafodion keytab reside
#
# This script makes a call to krb5check and accepts the following parameters:
# (changes are required if different defaults are needed)
# -c <cache location> location of Kerberos cache,
# (defaults to /tmp/krb5cc_uid)
# -w <wnum> time (in seconds) to wait before checking ticket expiration,
# (defaults to 5 minutes)
# -r <rnum> when to display ticket status to the log file,
# (defaults to 12 times which is 60 minutes ( <wnum> * <rnum>)
# ------------------------------------------------------------------------------
source krb5functions
# =================================================
# msg:
# write a message the log
# =================================================
function msg
{
echo "krb5service[$$] `date`: $1"
echo "krb5service[$$] `date`: $1" >> $LOG_FILE
}
# =================================================
# Main
# =================================================
LOCK_FILE=""
getLockFile
LOG_FILE=""
getLogFile
CACHE_FILE=""
KEYTAB=""
getKeytab
currentPID="NC"
if [ -f $LOCK_FILE ]; then
PID=$( cat $LOCK_FILE )
fi
# if LOCK_FILE contains digits, then good PID exists
if [[ $PID = *[[:digit:]]* ]]; then
currentPID=`ps -p $PID | grep krb5check | awk '{print $1}'`
fi
# if the current kbr5check PID matches what is stored in LOCK_FILE
# then we have an active process
serviceRunning=0
if [[ $currentPID = *[[:digit:]]* ]]; then
if [ "$currentPID" == "$PID" ]; then
serviceRunning=1
fi
fi
# =========================================================================
# parse the request
doInit=0
doStart=0
doStatus=0
doStop=0
TICKET_STATUS=""
case "$1" in
init)
doInit=1
;;
restart)
doStop=1
doStart=1
;;
start)
doStart=1
;;
status)
doStatus=1
;;
stop)
doStop=1
;;
*)
echo $"Usage: $0 {init | restart | start | status | stop}"
exit 1
;;
esac
# =========================================================================
# Perform the <init> request
if [ $doInit -eq 1 ]; then
msg "service init requested"
# get keytab
msg "using keytab: $KEYTAB"
# get principal
# if cached ticket exists, extract principal from cached location
# else ask kerberos for a list of principals based on the keytab, assume
# only one entry is returned (??)
HOST_NAME=`hostname -f`
getCachedTicket
if [[ $? -eq 0 ]]; then
PRINCIPAL="$( klist -c $CACHE_FILE | grep 'Default principal' | awk '{print $3}' )"
else
PRINCIPAL=`klist -kt $KEYTAB | grep $HOST_NAME | awk '{print $4}' | uniq`
fi
valid=`echo $PRINCIPAL | grep "$HOST_NAME" | wc -l`
if [[ $valid -eq 0 ]]; then
msg "Could not find valid principal ($PRINCIPAL)"
exit 1
fi
msg "using principal: $PRINCIPAL"
kinit -k -t $KEYTAB $PRINCIPAL
if [ $? -ne 0 ]; then
msg "An error occurred while initializing $PRINCIPAL"
exit 1
else
msg "Initialized ticket for principal $PRINCIPAL"
msg "`klist`"
fi
exit 0
fi
# =========================================================================
# Perform the <status> request
#
# returns:
# 0 - valid ticket
# 1 - no ticket
# 2 - expired or ready to expire ticket
if [ $doStatus -eq 1 ]; then
if [ $serviceRunning -eq 0 ]; then
echo "service not running"
fi
getCachedTicket
if [[ $? -eq 0 ]]; then
getStatus
retcode=$?
echo $TICKET_STATUS
else
echo "Ticket information not found"
retcode=1
fi
exit $retcode
fi
# =========================================================================
# Perform the <stop> request
if [ $doStop -eq 1 ]; then
msg "service stop requested"
if [ $serviceRunning -eq 1 ]; then
msg "service is running"
kill -9 $currentPID
rm $LOCK_FILE
msg "service stopped for $currentPID"
fi
fi
# =========================================================================
# Perform the <start> request
if [ $doStart -eq 1 ]; then
msg "service start requested"
# If the lockfile already exists then another process must be running
if [ -f $LOCK_FILE ]; then
if [ $serviceRunning -eq 1 ]; then
msg "service already running with pid $( cat $LOCK_FILE )"
exit 1
fi
fi
# remove log, may want to handle log garbage collection differently
rm $TRAF_HOME/logs/krb5check
# kick off a process that wakes up once in a while and check for
# ticket expirations
getCachedTicket
if [[ $? -eq 1 ]]; then
msg "ERROR: Ticket is not available"
fi
getStatus
msg "starting service (krb5check)"
msg "$TICKET_STATUS"
$TRAF_HOME/sql/scripts/krb5check -r 2 -w 300 &
krb5checkPID=`echo $!`
# see if process started successfully
sleep 5
existingPID=`ps -p $krb5checkPID | grep krb5check | awk '{print $1}'`
if [ ! "$existingPID" == "$krb5checkPID" ]; then
msg "service (krb5check) did not start, check $LOG_FILE for details"
fi
fi
# =========================================================================
exit 0