aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--laps.spec6
-rw-r--r--src/usr/share/doc/laps/README.md4
-rw-r--r--src/usr/share/doc/laps/changes4
-rw-r--r--src/usr/share/doc/laps/version.txt2
-rwxr-xr-xsrc/usr/share/laps/laps.sh76
5 files changed, 64 insertions, 28 deletions
diff --git a/laps.spec b/laps.spec
index da57c47..303a66d 100644
--- a/laps.spec
+++ b/laps.spec
@@ -1,6 +1,6 @@
%define debug_package %{nil}
Name: laps
-Version: 0.0.2
+Version: 0.0.3
Release: 1
Summary: local administrator password solution
@@ -44,5 +44,5 @@ cp -pr %{name}*/src/* "%{buildroot}"
%{_datadir}/%{name}
%changelog
-* Wed Oct 24 2018 B Stack <bgstack15@gmail.com> 0.0.2-1
-- initial rpm built
+* Fri Mar 1 2019 B Stack <bgstack15@gmail.com> 0.0.3-1
+- rpm built
diff --git a/src/usr/share/doc/laps/README.md b/src/usr/share/doc/laps/README.md
index 204b97d..7b5c95f 100644
--- a/src/usr/share/doc/laps/README.md
+++ b/src/usr/share/doc/laps/README.md
@@ -12,6 +12,10 @@ See /etc/laps/laps.conf.example for how to configure the client.
The administrator needs to write **/etc/laps/laps.conf** and **/etc/laps/lapsldap.conf**. Copying and modifying the example config files is the recommended way to provide the configs.
+For first use, use the -f flag to force the password change so the timestamp is initialized.
+
+ /usr/share/laps/laps.sh -f
+
# Prepare the domain
The OU where the Linux systems are placed in the domain will need some ACLS set up, which are identical to what the LAPS documentation describes. For a brief summary:
diff --git a/src/usr/share/doc/laps/changes b/src/usr/share/doc/laps/changes
index 9566fdc..51a0c15 100644
--- a/src/usr/share/doc/laps/changes
+++ b/src/usr/share/doc/laps/changes
@@ -2,3 +2,7 @@
- fix $2 read action should provide date of expiration on -d 1
- fix #3 add readme.md to front directory
- fix #4 laps does not recognize expired kerberos tickets
+
+* Mar 1 2019 B Stack <bgstack15@gmail.com> 0.0.3-1
+- fix #5 document the recommended use of "-f" for first run
+- merge !1 handle empty password change timestamp LDAP attribute
diff --git a/src/usr/share/doc/laps/version.txt b/src/usr/share/doc/laps/version.txt
index 4e379d2..bcab45a 100644
--- a/src/usr/share/doc/laps/version.txt
+++ b/src/usr/share/doc/laps/version.txt
@@ -1 +1 @@
-0.0.2
+0.0.3
diff --git a/src/usr/share/laps/laps.sh b/src/usr/share/laps/laps.sh
index 15280d3..c81e7a4 100755
--- a/src/usr/share/laps/laps.sh
+++ b/src/usr/share/laps/laps.sh
@@ -6,7 +6,7 @@
# Title: Local Administrator Password Solution for Linux
# Purpose: LAPS Equivalent for GNU/Linux
# Package: laps
-# History:
+# History: see upstream project at https://gitlab.com/bgstack15/laps
# Usage:
# Reference: ftemplate.sh 2018-09-12a; framework.sh 2018-09-12a
# Improve:
@@ -23,7 +23,7 @@
# sed (sed)
# awk (gawk)
fiversion="2018-09-12a"
-lapsversion="2018-10-24b"
+lapsversion="2019-03-01a"
usage() {
${PAGER:-/usr/bin/less -F} >&2 <<ENDUSAGE
@@ -108,6 +108,7 @@ main_workflow() {
# 2. fetch timestamp from ldap
LAPS_epoch="$( wrapper_get_timestamp_from_ldap "${LAPS_LDAPSEARCH_BIN}" "${LAPS_LDAPSEARCH_FLAGS}" "${LAPS_LDAPSEARCH_FILTER}" "${LAPS_ATTRIB_TIME}" "${LAPS_LDAPCONF}" "${LAPS_DATETIME_PY}" "${LAPS_KRB5CC_TMPFILE}" )"
+ test $? -eq 0 || return 1
# 3. check timestamp to see if close to expiration
check_ts_against_expiration_threshold "${LAPS_THRESHOLD}" "${LAPS_epoch}" "${LAPS_FORCE}"
@@ -178,26 +179,44 @@ get_attrib_from_ldap() {
# execute to check for ldap or kerberos errors
___gtfl_stderr="$( KRB5CCNAME="${___gtfl_krb5cc_tmpfile}" LDAPCONF="${___gtfl_ldapconf}" "${___gtfl_ldapsearch_bin}" ${___gtfl_ldapsearch_flags} "${___gtfl_ldapsearch_filter}" "${___gtfl_attrib}" 2>&1 1>/dev/null )"
- if echo "${___gtfl_stderr}" | grep -qiE 'Ticket expired' ;
+ if test "$?" -ne 0 ;
then
- ferror "Kerberos ticket expired. Any values from ldap will be garbage."
- elif echo "${___gtfl_stderr}" | grep -qi -e 'SASL(-1): generic failure: GSSAPI Error: An invalid name was supplied (Success)' ;
- then
- ferror "GSSAPI Error: Invalid name (Success). Try using \"SASL_NOCANON on\" in lapsldap.conf. Any values from ldap will be garbage."
- elif echo "${___gtfl_stderr}" | grep -qi -e 'TLS: hostname does not match CN in peer certificate' ;
- then
- ferror "TLS: hostname does not match CN. Try using \"TLS_REQCERT allow\" in lapsldap.conf. Any values from ldap will be garbage."
- else
- {
- echo "other ldap error:"
- echo "${___gtfl_stderr}"
- } | debuglevoutput 9
+ if echo "${___gtfl_stderr}" | grep -qiE 'Ticket expired' ;
+ then
+ ferror "Fatal: Kerberos ticket expired."
+ return 1;
+ elif echo "${___gtfl_stderr}" | grep -qi -e 'SASL(-1): generic failure: GSSAPI Error: An invalid name was supplied (Success)' ;
+ then
+ ferror "Fatal: GSSAPI Error: Invalid name (Success). Try using \"SASL_NOCANON on\" in lapsldap.conf."
+ return 1;
+ elif echo "${___gtfl_stderr}" | grep -qi -e 'TLS: hostname does not match CN in peer certificate' ;
+ then
+ ferror "Fatal: TLS: hostname does not match CN. Try using \"TLS_REQCERT allow\" in lapsldap.conf."
+ return 1;
+ else
+ {
+ echo "Fatal: other ldap error:"
+ echo "${___gtfl_stderr}"
+ } | debuglevoutput 9
+ return 1;
+ fi
fi
# execute for actually fetching the value
- ___gtfl_attrib="$( KRB5CCNAME="${___gtfl_krb5cc_tmpfile}" LDAPCONF="${___gtfl_ldapconf}" "${___gtfl_ldapsearch_bin}" ${___gtfl_ldapsearch_flags} "${___gtfl_ldapsearch_filter}" "${___gtfl_attrib}" 2>/dev/null | sed -r -e 's/^#.*$//;' -e '/^\s*$/d' | grep -iE -e "^${___gtfl_attrib}:" | awk '{print $2}' )"
+ ___gtfl_attrib="$( { KRB5CCNAME="${___gtfl_krb5cc_tmpfile}" LDAPCONF="${___gtfl_ldapconf}" \
+ "${___gtfl_ldapsearch_bin}" ${___gtfl_ldapsearch_flags} "${___gtfl_ldapsearch_filter}" \
+ "${___gtfl_attrib}" 2>/dev/null ; \
+ echo "$?" > "${LAPS_LDAPSEARCH_STATUS_TMPFILE}" ; \
+ } | sed -r -e 's/^#.*$//;' -e '/^\s*$/d' | grep -iE -e "^${___gtfl_attrib}:" | awk '{print $2}' )"
+ ___gtfl_ldap_success="$( { cat "${LAPS_LDAPSEARCH_STATUS_TMPFILE}" 2>/dev/null ; echo "1" ; } | head -n1 )"
+ if test "${___gtfl_ldap_success}" != "0" ;
+ then
+ ferror "Fatal: LDAP lookup failed"
+ return 1
+ fi
- # no value means either the ldap connection malfunctioned or there was no attribute by that name defined.
+ # here we can be sure that an empty value means there was no attribute by
+ # that name defined or it had an actual empty value.
echo "${___gtfl_attrib}"
@@ -215,8 +234,14 @@ wrapper_get_timestamp_from_ldap() {
___wgtfl_krb5cc_tmpfile="${7}"
ts_filetime="$( get_attrib_from_ldap "${___wgtfl_ldapsearch_bin}" "${___wgtfl_ldapsearch_flags}" "${___wgtfl_ldapsearch_filter}" "${___wgtfl_attrib}" "${___wgtfl_ldapconf}" "${___wgtfl_krb5cc_tmpfile}" )"
- debuglev 3 && ferror "timestamp(FILETIME): ${ts_filetime}"
- ts_epoch="$( "${___wgtfl_datetime_py}" -e "${ts_filetime}" )"
+ test "$?" -eq 0 || return 1
+
+ ts_epoch=0
+ if test -n "$ts_filetime" ;
+ then
+ debuglev 3 && ferror "timestamp(FILETIME): ${ts_filetime}"
+ ts_epoch="$( "${___wgtfl_datetime_py}" -e "${ts_filetime}" )"
+ fi
debuglev 2 && ferror "timestamp(epoch): ${ts_epoch}"
debuglev 1 && ferror "timestamp(UTC): $( date -u -d "@${ts_epoch}" "+%FT%TZ" )"
@@ -373,7 +398,7 @@ wrapper_change_password() {
then
echo "0" > "${LAPS_PASSWORD_STATUS_TMPFILE}"
else
- ___wcp_stdout="$( echo -e "$(echo ${___wcp_phrase})\n$(echo ${___wcp_phrase})" | "${___wcp_passwd_bin}" "${___wcp_user}" ; echo "$?" > "${LAPS_PASSWORD_STATUS_TMPFILE}" )"
+ ___wcp_stdout="$( printf "%s\n%s\n" "${___wcp_phrase}" "${___wcp_phrase}" | "${___wcp_passwd_bin}" "${___wcp_user}" ; echo "$?" > "${LAPS_PASSWORD_STATUS_TMPFILE}" )"
fi
___wcp_passwd_result="$( cat "${LAPS_PASSWORD_STATUS_TMPFILE}" )"
@@ -383,7 +408,7 @@ wrapper_change_password() {
debuglev 4 && ferror "${___wcp_stdout}"
;;
*)
- # successful operation
+ # failed operation
ferror "${scriptfile}: 8 fatal! Unable to change password for ${___wcp_user}:\n${___wcp_stdout}"
exit 8
;;
@@ -504,8 +529,8 @@ clean_laps() {
# Delayed cleanup
if test -z "${LAPS_NO_CLEAN}" ;
then
- nohup /bin/bash <<EOF 1>/dev/null 2>&1 &
-sleep "${LAPS_CLEANUP_SEC:-300}" ; /bin/rm -r "${LAPS_TMPDIR:-NOTHINGTODELETE}" 1>/dev/null 2>&1 ;
+ nohup /bin/sh <<EOF 1>/dev/null 2>&1 &
+sleep "${LAPS_CLEANUP_SEC:-3}" ; /bin/rm -r "${LAPS_TMPDIR:-NOTHINGTODELETE}" 1>/dev/null 2>&1 ;
EOF
fi
}
@@ -634,6 +659,7 @@ test -z "${LAPS_TMPDIR}" && LAPS_TMPDIR="$( mktemp -d /tmp/laps.XXXXXXXXXX )"
test -z "${LAPS_KRB5CC_TMPFILE}" && LAPS_KRB5CC_TMPFILE="$( TMPDIR="${LAPS_TMPDIR}" mktemp )"
test -z "${LAPS_LDIF_TMPFILE}" && LAPS_LDIF_TMPFILE="$( TMPDIR="${LAPS_TMPDIR}" mktemp )"
test -z "${LAPS_LDAPMODIFY_STATUS_TMPFILE}" && LAPS_LDAPMODIFY_STATUS_TMPFILE="$( TMPDIR="${LAPS_TMPDIR}" mktemp )"
+test -z "${LAPS_LDAPSEARCH_STATUS_TMPFILE}" && LAPS_LDAPSEARCH_STATUS_TMPFILE="$( TMPDIR="${LAPS_TMPDIR}" mktemp )"
test -z "${LAPS_PASSWORD_STATUS_TMPFILE}" && LAPS_PASSWORD_STATUS_TMPFILE="$( TMPDIR="${LAPS_TMPDIR}" mktemp )"
define_if_new LAPS_KINIT_HOST_SCRIPT "/usr/share/bgscripts/work/kinit-host.sh"
define_if_new LAPS_KINIT_HOST_SCRIPT_DEFAULT "/usr/share/bgscripts/work/kinit-host.sh"
@@ -676,7 +702,9 @@ define_if_new LAPS_INTERACTIVE 0
# SET TRAPS
#trap "CTRLC" 2
#trap "CTRLZ" 18
-trap '__ec=$? ; clean_laps ; trap "" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; exit ${__ec} ;' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+# do NOT catch SIGCHLD (17) because dash will actually exit then (bash seems to
+# ignore our attempt to catch it)
+trap '__ec=$? ; clean_laps ; trap "" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 ; exit ${__ec} ;' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20
# DEBUG SIMPLECONF
debuglev 5 && {
bgstack15