From 6229f0327a532b21c970a2d3cd1c2bbec99421c4 Mon Sep 17 00:00:00 2001 From: cmyers-mieweb Date: Thu, 2 Apr 2026 13:41:41 -0700 Subject: [PATCH 1/3] Add LDAP-based git identity and SSSD config Install ldap-utils and add LDAP client/config and a profile script to auto-configure git user.name/email from LDAP on first interactive login. Copies ldap.conf to /etc/ldap, adds /etc/profile.d/git-identity.sh which uses ldapsearch and NSS (sssd) gecos to set global git config, and adjusts sssd.conf to map cn -> gecos (ldap_user_gecos = cn). Also updates Dockerfile to install ldap-utils and include the new files. --- images/base/Dockerfile | 8 ++++++-- images/base/git-identity.sh | 40 +++++++++++++++++++++++++++++++++++++ images/base/ldap.conf | 5 +++++ images/base/sssd.conf | 4 ++++ 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 images/base/git-identity.sh create mode 100644 images/base/ldap.conf diff --git a/images/base/Dockerfile b/images/base/Dockerfile index 76c54704..ed307a3b 100644 --- a/images/base/Dockerfile +++ b/images/base/Dockerfile @@ -12,14 +12,18 @@ RUN mkdir /rootfs && curl "$URL" | tar --zstd -x -C /rootfs FROM scratch COPY --from=builder /rootfs / -# Install and setup sssd autoconfiguration +# Install and setup sssd autoconfiguration. +# ldap-utils provides ldapsearch, used by the git-identity profile script to +# fetch a user's email from the internal LDAP server on first interactive login. RUN apt-get update && \ - apt-get install -y sssd sudo tmux curl gnupg git jq unattended-upgrades && \ + apt-get install -y sssd sudo tmux curl gnupg git jq ldap-utils unattended-upgrades && \ pam-auth-update --enable mkhomedir && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* COPY --chmod=0440 sssd.conf /etc/sssd/sssd.conf COPY --chmod=0440 ldapusers /etc/sudoers.d/ldapusers +COPY --chmod=0644 ldap.conf /etc/ldap/ldap.conf +COPY --chmod=0755 git-identity.sh /etc/profile.d/git-identity.sh # The following service ensures environment variables set in the OCI metadata # or container configuration are passed to programs executed by systemd which diff --git a/images/base/git-identity.sh b/images/base/git-identity.sh new file mode 100644 index 00000000..4da85720 --- /dev/null +++ b/images/base/git-identity.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Automatically configures git user.name and user.email from the user's LDAP +# profile on first interactive login to a container. Subsequent logins skip +# this entirely once git config is set. +# +# The name is read from the NSS gecos field (mapped from LDAP cn via sssd.conf). +# The email is read from LDAP via an anonymous ldapsearch (REQUIRE_AUTH_FOR_SEARCH +# is disabled on the internal ldap-gateway, so no bind credentials are needed). + +# Only run for interactive shells +[[ $- != *i* ]] && return + +# Only if git is available +command -v git >/dev/null 2>&1 || return +command -v ldapsearch >/dev/null 2>&1 || return + +# Skip if already configured — user-set values always take precedence +[ -n "$(git config --global user.email 2>/dev/null)" ] && return + +_GIT_SETUP_USER="${USER:-$(id -un 2>/dev/null)}" +[ -z "$_GIT_SETUP_USER" ] && return + +# Full name from NSS (SSSD maps LDAP cn -> gecos via ldap_user_gecos = cn) +_GIT_SETUP_NAME=$(getent passwd "$_GIT_SETUP_USER" 2>/dev/null | cut -d: -f5) + +# Email from LDAP anonymous query +_GIT_SETUP_LDAP_HOST="${LDAP_URI:-ldaps://ldap1:636}" +_GIT_SETUP_LDAP_BASE="${LDAP_BASE_DN:-dc=docker,dc=internal}" +_GIT_SETUP_EMAIL=$(ldapsearch -x \ + -H "$_GIT_SETUP_LDAP_HOST" \ + -b "$_GIT_SETUP_LDAP_BASE" \ + "(uid=${_GIT_SETUP_USER})" mail 2>/dev/null \ + | awk '/^mail:/{print $2; exit}') + +if [ -n "$_GIT_SETUP_NAME" ] && [ -n "$_GIT_SETUP_EMAIL" ]; then + git config --global user.name "$_GIT_SETUP_NAME" + git config --global user.email "$_GIT_SETUP_EMAIL" +fi + +unset _GIT_SETUP_USER _GIT_SETUP_NAME _GIT_SETUP_EMAIL _GIT_SETUP_LDAP_HOST _GIT_SETUP_LDAP_BASE diff --git a/images/base/ldap.conf b/images/base/ldap.conf new file mode 100644 index 00000000..ba75df65 --- /dev/null +++ b/images/base/ldap.conf @@ -0,0 +1,5 @@ +# OpenLDAP client configuration for containers. +# Mirrors the TLS check level used by SSSD (ldap_tls_reqcert = allow) so that +# ldapsearch and other ldap-utils tools accept the internal certificate without +# additional flags. +TLS_REQCERT allow diff --git a/images/base/sssd.conf b/images/base/sssd.conf index 3086ee24..73d486cf 100644 --- a/images/base/sssd.conf +++ b/images/base/sssd.conf @@ -7,5 +7,9 @@ auth_provider = ldap ldap_uri = ldaps://ldap1:636, ldaps://ldap2:636 ldap_tls_reqcert = allow +# Map LDAP cn attribute to the NSS gecos field so that tools like getent, +# finger, and the git-identity profile script can read the user's full name. +ldap_user_gecos = cn + # set a timeout long enough for a push notification to be responded to ldap_opt_timeout = 60 From acda133285bd3c1e58a4c213a0fc091ce05c9c03 Mon Sep 17 00:00:00 2001 From: cmyers-mieweb Date: Thu, 2 Apr 2026 13:41:41 -0700 Subject: [PATCH 2/3] Add LDAP-based git identity and SSSD config Install ldap-utils and add LDAP client/config and a profile script to auto-configure git user.name/email from LDAP on first interactive login. Copies ldap.conf to /etc/ldap, adds /etc/profile.d/git-identity.sh which uses ldapsearch and NSS (sssd) gecos to set global git config, and adjusts sssd.conf to map cn -> gecos (ldap_user_gecos = cn). Also updates Dockerfile to install ldap-utils and include the new files. --- images/base/Dockerfile | 8 ++++++-- images/base/git-identity.sh | 40 +++++++++++++++++++++++++++++++++++++ images/base/ldap.conf | 5 +++++ images/base/sssd.conf | 4 ++++ 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 images/base/git-identity.sh create mode 100644 images/base/ldap.conf diff --git a/images/base/Dockerfile b/images/base/Dockerfile index 76c54704..ed307a3b 100644 --- a/images/base/Dockerfile +++ b/images/base/Dockerfile @@ -12,14 +12,18 @@ RUN mkdir /rootfs && curl "$URL" | tar --zstd -x -C /rootfs FROM scratch COPY --from=builder /rootfs / -# Install and setup sssd autoconfiguration +# Install and setup sssd autoconfiguration. +# ldap-utils provides ldapsearch, used by the git-identity profile script to +# fetch a user's email from the internal LDAP server on first interactive login. RUN apt-get update && \ - apt-get install -y sssd sudo tmux curl gnupg git jq unattended-upgrades && \ + apt-get install -y sssd sudo tmux curl gnupg git jq ldap-utils unattended-upgrades && \ pam-auth-update --enable mkhomedir && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* COPY --chmod=0440 sssd.conf /etc/sssd/sssd.conf COPY --chmod=0440 ldapusers /etc/sudoers.d/ldapusers +COPY --chmod=0644 ldap.conf /etc/ldap/ldap.conf +COPY --chmod=0755 git-identity.sh /etc/profile.d/git-identity.sh # The following service ensures environment variables set in the OCI metadata # or container configuration are passed to programs executed by systemd which diff --git a/images/base/git-identity.sh b/images/base/git-identity.sh new file mode 100644 index 00000000..4da85720 --- /dev/null +++ b/images/base/git-identity.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Automatically configures git user.name and user.email from the user's LDAP +# profile on first interactive login to a container. Subsequent logins skip +# this entirely once git config is set. +# +# The name is read from the NSS gecos field (mapped from LDAP cn via sssd.conf). +# The email is read from LDAP via an anonymous ldapsearch (REQUIRE_AUTH_FOR_SEARCH +# is disabled on the internal ldap-gateway, so no bind credentials are needed). + +# Only run for interactive shells +[[ $- != *i* ]] && return + +# Only if git is available +command -v git >/dev/null 2>&1 || return +command -v ldapsearch >/dev/null 2>&1 || return + +# Skip if already configured — user-set values always take precedence +[ -n "$(git config --global user.email 2>/dev/null)" ] && return + +_GIT_SETUP_USER="${USER:-$(id -un 2>/dev/null)}" +[ -z "$_GIT_SETUP_USER" ] && return + +# Full name from NSS (SSSD maps LDAP cn -> gecos via ldap_user_gecos = cn) +_GIT_SETUP_NAME=$(getent passwd "$_GIT_SETUP_USER" 2>/dev/null | cut -d: -f5) + +# Email from LDAP anonymous query +_GIT_SETUP_LDAP_HOST="${LDAP_URI:-ldaps://ldap1:636}" +_GIT_SETUP_LDAP_BASE="${LDAP_BASE_DN:-dc=docker,dc=internal}" +_GIT_SETUP_EMAIL=$(ldapsearch -x \ + -H "$_GIT_SETUP_LDAP_HOST" \ + -b "$_GIT_SETUP_LDAP_BASE" \ + "(uid=${_GIT_SETUP_USER})" mail 2>/dev/null \ + | awk '/^mail:/{print $2; exit}') + +if [ -n "$_GIT_SETUP_NAME" ] && [ -n "$_GIT_SETUP_EMAIL" ]; then + git config --global user.name "$_GIT_SETUP_NAME" + git config --global user.email "$_GIT_SETUP_EMAIL" +fi + +unset _GIT_SETUP_USER _GIT_SETUP_NAME _GIT_SETUP_EMAIL _GIT_SETUP_LDAP_HOST _GIT_SETUP_LDAP_BASE diff --git a/images/base/ldap.conf b/images/base/ldap.conf new file mode 100644 index 00000000..ba75df65 --- /dev/null +++ b/images/base/ldap.conf @@ -0,0 +1,5 @@ +# OpenLDAP client configuration for containers. +# Mirrors the TLS check level used by SSSD (ldap_tls_reqcert = allow) so that +# ldapsearch and other ldap-utils tools accept the internal certificate without +# additional flags. +TLS_REQCERT allow diff --git a/images/base/sssd.conf b/images/base/sssd.conf index 3086ee24..73d486cf 100644 --- a/images/base/sssd.conf +++ b/images/base/sssd.conf @@ -7,5 +7,9 @@ auth_provider = ldap ldap_uri = ldaps://ldap1:636, ldaps://ldap2:636 ldap_tls_reqcert = allow +# Map LDAP cn attribute to the NSS gecos field so that tools like getent, +# finger, and the git-identity profile script can read the user's full name. +ldap_user_gecos = cn + # set a timeout long enough for a push notification to be responded to ldap_opt_timeout = 60 From d16a353d3cc8a8730d92556d4c0cba11abacaaef Mon Sep 17 00:00:00 2001 From: cmyers-mieweb Date: Wed, 8 Apr 2026 09:54:29 -0700 Subject: [PATCH 3/3] Improve git identity discovery & LDAP base resolution Enhance git-identity.sh to be more robust: only skip when both global user.name and user.email are set, ignore root, resolve LDAP baseDN via RootDSE (namingContexts / defaultNamingContext) when LDAP_BASE_DN isn't provided, and set user.name (from NSS gecos) and user.email (from LDAP) independently. Clean up temporary variables. Also remove the explicit ldap_user_gecos = cn mapping from sssd.conf since SSSD reads gecos by default; aligns git identity logic with SSSD behavior and handles multi-entry namingContexts. --- images/base/git-identity.sh | 33 ++++++++++++++++++++++++++++----- images/base/sssd.conf | 4 ---- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/images/base/git-identity.sh b/images/base/git-identity.sh index 4da85720..2f80e516 100644 --- a/images/base/git-identity.sh +++ b/images/base/git-identity.sh @@ -15,26 +15,49 @@ command -v git >/dev/null 2>&1 || return command -v ldapsearch >/dev/null 2>&1 || return # Skip if already configured — user-set values always take precedence -[ -n "$(git config --global user.email 2>/dev/null)" ] && return +[ -n "$(git config --global user.email 2>/dev/null)" ] && [ -n "$(git config --global user.name 2>/dev/null)" ] && return _GIT_SETUP_USER="${USER:-$(id -un 2>/dev/null)}" [ -z "$_GIT_SETUP_USER" ] && return +[ "$_GIT_SETUP_USER" = "root" ] && return -# Full name from NSS (SSSD maps LDAP cn -> gecos via ldap_user_gecos = cn) +# Full name from NSS (SSSD reads the LDAP gecos attribute by default via ldap_user_gecos) _GIT_SETUP_NAME=$(getent passwd "$_GIT_SETUP_USER" 2>/dev/null | cut -d: -f5) # Email from LDAP anonymous query _GIT_SETUP_LDAP_HOST="${LDAP_URI:-ldaps://ldap1:636}" -_GIT_SETUP_LDAP_BASE="${LDAP_BASE_DN:-dc=docker,dc=internal}" + +# Resolve baseDN the same way SSSD does: rootDSE namingContexts autodiscovery. +# Use LDAP_BASE_DN if explicitly set; otherwise query rootDSE. +# - Single namingContexts entry -> use it directly +# - Multiple namingContexts -> use defaultNamingContext +# - Neither resolvable -> abort +if [ -n "${LDAP_BASE_DN:-}" ]; then + _GIT_SETUP_LDAP_BASE="$LDAP_BASE_DN" +else + _GIT_SETUP_ROOTDSE=$(ldapsearch -x -H "$_GIT_SETUP_LDAP_HOST" -b "" -s base namingContexts defaultNamingContext 2>/dev/null) + _GIT_SETUP_NC_COUNT=$(echo "$_GIT_SETUP_ROOTDSE" | grep -c '^namingContexts:') + if [ "$_GIT_SETUP_NC_COUNT" -eq 1 ]; then + _GIT_SETUP_LDAP_BASE=$(echo "$_GIT_SETUP_ROOTDSE" | awk '/^namingContexts:/{print $2; exit}') + elif [ "$_GIT_SETUP_NC_COUNT" -gt 1 ]; then + _GIT_SETUP_LDAP_BASE=$(echo "$_GIT_SETUP_ROOTDSE" | awk '/^defaultNamingContext:/{print $2; exit}') + fi + unset _GIT_SETUP_ROOTDSE _GIT_SETUP_NC_COUNT +fi +[ -z "${_GIT_SETUP_LDAP_BASE:-}" ] && return + _GIT_SETUP_EMAIL=$(ldapsearch -x \ -H "$_GIT_SETUP_LDAP_HOST" \ -b "$_GIT_SETUP_LDAP_BASE" \ "(uid=${_GIT_SETUP_USER})" mail 2>/dev/null \ | awk '/^mail:/{print $2; exit}') -if [ -n "$_GIT_SETUP_NAME" ] && [ -n "$_GIT_SETUP_EMAIL" ]; then +if [ -n "$_GIT_SETUP_NAME" ]; then git config --global user.name "$_GIT_SETUP_NAME" +fi + +if [ -n "$_GIT_SETUP_EMAIL" ]; then git config --global user.email "$_GIT_SETUP_EMAIL" fi -unset _GIT_SETUP_USER _GIT_SETUP_NAME _GIT_SETUP_EMAIL _GIT_SETUP_LDAP_HOST _GIT_SETUP_LDAP_BASE +unset _GIT_SETUP_USER _GIT_SETUP_NAME _GIT_SETUP_EMAIL _GIT_SETUP_LDAP_HOST _GIT_SETUP_LDAP_BASE _GIT_SETUP_ROOTDSE _GIT_SETUP_NC_COUNT diff --git a/images/base/sssd.conf b/images/base/sssd.conf index 73d486cf..3086ee24 100644 --- a/images/base/sssd.conf +++ b/images/base/sssd.conf @@ -7,9 +7,5 @@ auth_provider = ldap ldap_uri = ldaps://ldap1:636, ldaps://ldap2:636 ldap_tls_reqcert = allow -# Map LDAP cn attribute to the NSS gecos field so that tools like getent, -# finger, and the git-identity profile script can read the user's full name. -ldap_user_gecos = cn - # set a timeout long enough for a push notification to be responded to ldap_opt_timeout = 60