#!/bin/bash
#==============================================================================
# Copyright and license info is available in the LICENSE file included with
# the Server Deployment Package (SDP), and also available online:
# https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE
#------------------------------------------------------------------------------
set -u
# p4login generates a login ticket for the SDP super user. It is called
# from cron scripts, and so does not normally generate output to stdout or
# stderr.
#
# Normally output (stdout and stderr) is logged in $LOGS/p4login.log,
# unless unless SDP_INSTANCE isn't defined, in which case it bails
# immediately.
#
# An exit code of 0 indicates a valid login ticket exists, while a
# non-zero exit code indicates a failure to login.
export SDP_INSTANCE=${SDP_INSTANCE:-Unset}
export SDP_INSTANCE=${1:-$SDP_INSTANCE}
declare -i SDP_ALWAYS_LOGIN=${SDP_ALWAYS_LOGIN:-1}
declare AutomationUsers=${SDP_AUTOMATION_USERS:-""}
declare AuthID=
declare AuthServerPort=
declare Cmd=
declare UserType=
declare ServiceUser=
declare TargetServerPort=
declare TicketExpiration=
declare Log=Unset
declare Version=3.1.4
declare -i OverallExitCode=0
declare -i LoginCount=0
function msg () { if [[ $Log != Unset ]]; then echo -e "$*" >> $Log; else echo -e "$*"; fi; }
function cmd () { msg "Executing: $*" >> $Log; $* >> $Log 2>&1 ; return $?; }
function bail () { msg "\nError: ${1:-Unknown Error}"; exit ${2:-1}; }
function login_user () {
declare user=$1
declare port=$2
declare userType=
userType=$($P4BIN -ztag -F %Type% user -o $user)
userType=${userType:-unknown}
msg "Logging user $user (type=$userType) into port: $port."
TicketExpiration=$($P4BIN -ztag -F %TicketExpiration% -p $port -u $user login -s 2>/dev/null)
if [[ $TicketExpiration =~ [0-9]+ ]]; then
# A 'long-term' ticket is one that expires more than a month (31 days + 1 second) from now.
if [[ $TicketExpiration -ge 2678401 ]]; then
msg "User $user logged into $P4PORT with a long-term ticket. Login not required."
if [[ $SDP_ALWAYS_LOGIN -eq 1 ]]; then
msg "Doing login anyway as SDP_ALWAYS_LOGIN is enabled."
if [[ $user == $P4USER ]]; then
Cmd="$P4BIN -p $port -u $user -s login -a"
msg Running: $Cmd
$Cmd < /p4/common/bin/adminpass >> $Log 2>&1 || return 1
LoginCount=$((LoginCount+1))
else
if [[ $userType == service ]]; then
Cmd="$P4BIN -p $port -u $P4USER -s login $user"
else
Cmd="$P4BIN -p $port -u $P4USER -s login -a $user"
fi
msg Running: $Cmd
$Cmd >> $Log 2>&1 || return 1
LoginCount=$((LoginCount+1))
fi
fi
return 0
else
msg "Warning: User $user logged into $P4PORT with a short-term ticket. Attempting to extend."
if [[ $user == $P4USER ]]; then
Cmd="$P4BIN -p $port -u $P4USER -s login -a"
msg Running: $Cmd
$Cmd < /p4/common/bin/adminpass >> $Log 2>&1 || return 1
LoginCount=$((LoginCount+1))
else
Cmd="$P4BIN -p $port -u $P4USER -s login -a $user"
msg Running: $Cmd
$Cmd >> $Log 2>&1 || return 1
LoginCount=$((LoginCount+1))
fi
fi
else
msg "User $user is not logged into $P4PORT. Attempting to login."
if [[ $user == $P4USER ]]; then
Cmd="$P4BIN -p $port -u $P4USER -s login -a"
msg Running: $Cmd
$Cmd < /p4/common/bin/adminpass >> $Log 2>&1 || return 1
LoginCount=$((LoginCount+1))
else
# We cannot use the '-a' flag to 'p4 login' for service accounts, so drop it
# for service accounts. Otherwise, '-a' is preferred for robustness, since
# certain network interface card (NIC) configurations with multiple IPs need
# tickets not bound to one of multiple possible IPs. See 'p4 help login' for more.
if [[ $userType == service ]]; then
Cmd="$P4BIN -p $port -u $P4USER -s login $user"
else
Cmd="$P4BIN -p $port -u $P4USER -s login -a $user"
fi
msg Running: $Cmd
$Cmd >> $Log 2>&1 || return 1
LoginCount=$((LoginCount+1))
fi
fi
}
[[ $SDP_INSTANCE == Unset ]] && \
bail "The \$SDP_INSTANCE setting is not defined. It must be defined by doing:\n\n\tsource /p4/common/bin/p4_vars <instance>\n\nor by passing in the instance name as a parameter to this script.\n"
source /p4/common/bin/p4_vars $SDP_INSTANCE || bail "Failed to load SDP environment for instance $SDP_INSTANCE."
Log=$LOGS/p4login.log
rm -f "$Log"
msg "${0##*/} v$Version Checking login status at $(date +'%a %Y-%m-%d %H:%M:%S %Z').\n"
cmd p4 set P4TICKETS
AuthID=$($P4DBIN -cshow | grep "auth.id" | cut -d ' ' -f 4)
# Login the $P4USER super user first, whose password must match that in
# /p4/common/bin/adminpass.
# First, if we are on a replica/edge, login the service user and super user to the master
# server first, then to the local replica.
if [[ -n "$SERVERID" && "$SERVERID" != "$P4MASTER_ID" ]]; then
msg "\nDoing special replica/edge logins."
TargetServerPort=$($P4DBIN -cshow | grep "${SERVERID}: P4TARGET" | cut -d ' ' -f 4)
ServiceUser=$($P4DBIN -cshow | grep "${SERVERID}: serviceUser" | cut -d ' ' -f 4)
if [[ -n "$AuthID" ]]; then
msg "The auth.id configurable is set ($AuthID). Logging in to master P4PORT only."
if [[ -n "$TargetServerPort" && -n "$ServiceUser" ]]; then
login_user "$P4USER" "$TargetServerPort" || OverallExitCode=1
login_user "$ServiceUser" "$TargetServerPort" || OverallExitCode=1
else
msg "\nError: This is not the master (ServerID=$SERVERID), but could not determine P4TARGET and/or serviceUser for server $SERVERID."
OverallExitCode=1
login_user "$P4USER" "$TargetServerPort"
login_user "$ServiceUser" "$TargetServerPort"
fi
else
msg "The auth.id configurable is not set. Logging in to both local and P4TARGET ports."
if [[ -n "$TargetServerPort" && -n "$ServiceUser" ]]; then
login_user "$P4USER" "$TargetServerPort" || OverallExitCode=1
login_user "$P4USER" "$P4PORT" || OverallExitCode=1
login_user "$ServiceUser" "$TargetServerPort" || OverallExitCode=1
else
msg "\nError: This is not the master (ServerID=$SERVERID), but could not determine P4TARGET and/or serviceUser for server $SERVERID."
OverallExitCode=1
login_user "$P4USER" "$P4PORT"
fi
# AuthServerPort is the P4AUTH server; it is not related to the auth.id configurable. If a P4AUTH server
# is defined, we need to login there, too.
AuthServerPort=$($P4BIN -p $P4PORT configure show P4AUTH 2>/dev/null)
if [[ -n "$AuthServerPort" ]]; then
AuthServerPort=${AuthServerPort##*=}
AuthServerPort=${AuthServerPort%% *}
msg "Logging into P4AUTH server."
login_user "$ServiceUser" "$AuthServerPort" || OverallExitCode=1
fi
fi
else
msg "\nOperating on master/commit server, skipping replica/edge logins."
login_user "$P4USER" "$P4PORT" || OverallExitCode=1
fi
if [[ -n "$P4BROKERPORT" && "$P4BROKERPORT" != Unset ]]; then
msg Logging $P4USER into broker.
login_user "$P4USER" "$P4BROKERPORT" || OverallExitCode=1
fi
# Next, login other automation users (which may or may not be super users)
# using $P4USER's super powers to log them in without a password.
if [[ -n "$AutomationUsers" ]]; then
msg "\nLogging in special automation users defined by SDP_AUTOMATION_USERS setting in $P4CCFG/${P4SERVER}.vars."
for user in ${AutomationUsers/,/ }; do
msg "Logging in user $user."
login_user "$user" "$P4PORT" || OverallExitCode=1
if [[ -z "$AuthID" ]]; then
if [[ -n "$P4BROKERPORT" && "$P4BROKERPORT" != Unset ]]; then
login_user "$user" "$P4BROKERPORT" || OverallExitCode=1
fi
fi
done
fi
if [[ $OverallExitCode -eq 0 ]]; then
if [[ $LoginCount -gt 0 ]]; then
msg "\nSuccess: All logins were successful, $LoginCount login(s) were needed."
else
msg "\nSuccess: No logins were needed."
fi
else
msg "\nError: Some logins were not successful; $LoginCount were attempted. Review the output above."
fi
exit $OverallExitCode
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #24 | 32135 | C. Thomas Tyler |
Released SDP 2025.1.32133 (2025/10/29). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #23 | 31566 | C. Thomas Tyler |
Released SDP 2024.2.31564 (2025/05/14). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #22 | 31204 | Will Kreitzmann |
Released SDP 2024.2.31193 (2025/01/17). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #21 | 31077 | C. Thomas Tyler |
Released SDP 2024.2.31075 (2024/12/20). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #20 | 30297 | C. Thomas Tyler |
Released SDP 2023.2.30295 (2024/05/08). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #19 | 29443 | C. Thomas Tyler |
Released SDP 2022.2.29441 (2023/02/27). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #18 | 27761 | C. Thomas Tyler |
Released SDP 2020.1.27759 (2021/05/07). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #17 | 27331 | C. Thomas Tyler |
Released SDP 2020.1.27325 (2021/01/29). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #16 | 25933 | C. Thomas Tyler |
Released SDP 2019.2.25923 (2019/08/05). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #15 | 25245 | C. Thomas Tyler |
Released SDP 2019.1.25238 (2019/03/02). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #14 | 23331 | C. Thomas Tyler |
Released SDP 2017.4.23329 (2017/12/05). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #13 | 23044 | C. Thomas Tyler |
Released SDP 2017.3.23041 (2017/10/24). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #12 | 20839 | C. Thomas Tyler | Fixed quoting bug in p4login. | ||
| #11 | 20792 | C. Thomas Tyler |
Released SDP 2016.2.20790 (2016/09/30). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #10 | 20767 | C. Thomas Tyler |
Released SDP 2016.2.20755 (2016/09/29). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #9 | 20353 | C. Thomas Tyler |
Released SDP 2016.1.20348. Copy Up using 'p4 copy -r -b perforce_software-sdp-dev', with selective removal of changes related to work-in-progress changes. |
||
| #8 | 20050 | C. Thomas Tyler |
Released: 2016.1.20028 (2016/08/03). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| #7 | 18530 | Russell C. Jackson (Rusty) | Update main from dev. | ||
| #6 | 15865 | Russell C. Jackson (Rusty) | Removed space between $ and Log | ||
| #5 | 15856 | C. Thomas Tyler |
Replaced the big license comment block with a shortened form referencing the LICENSE file included with the SDP package, and also by the URL for the license file in The Workshop. |
||
| #4 | 15609 | C. Thomas Tyler | Pushing SDP 2015.1.15607 (2015/09/02). | ||
| #3 | 13908 | C. Thomas Tyler | Pushing SDP 2015.1.13906. | ||
| #2 | 12171 | Russell C. Jackson (Rusty) | Merge in changes to remove the need for p4master_run. | ||
| #1 | 10148 | C. Thomas Tyler | Promoted the Perforce Server Deployment Package to The Workshop. |