Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
845fb73ad1
|
|||
|
d0b5821e9a
|
|||
|
072c1f062f
|
@@ -3,7 +3,6 @@ name: Test Coverage
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
|
||||||
- 'coverage-*'
|
- 'coverage-*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -37,7 +36,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap --prefix=$HOME/inst CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap --prefix=$HOME/inst CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 40
|
|
||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
sudo sysctl kernel.core_pattern=core.%p || true
|
sudo sysctl kernel.core_pattern=core.%p || true
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ jobs:
|
|||||||
cd build
|
cd build
|
||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
||||||
ulimit -c unlimited
|
ulimit -c unlimited
|
||||||
# We don't want to scan-build SQLite3 because ETOOSLOW
|
# We don't want to scan-build libedit nor SQLite3 because ETOOSLOW
|
||||||
|
(cd lib/libedit && make -j4)
|
||||||
(cd lib/sqlite && make -j4)
|
(cd lib/sqlite && make -j4)
|
||||||
cov-build --dir cov-int make -j4
|
cov-build --dir cov-int make -j4
|
||||||
tar czvf ../heimdal.tgz cov-int
|
tar czvf ../heimdal.tgz cov-int
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations" --with-mitkrb5=$HOME/mitkrb5 --with-older-heimdal=$HOME/oh5l
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations" --with-mitkrb5=$HOME/mitkrb5 --with-older-heimdal=$HOME/oh5l
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 20
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'master'
|
||||||
- 'heimdal-7-1-branch'
|
- 'heimdal-7-1-branch'
|
||||||
- 'test-ILP32'
|
|
||||||
paths:
|
paths:
|
||||||
- '!docs/**'
|
- '!docs/**'
|
||||||
- '!**.md'
|
- '!**.md'
|
||||||
@@ -64,7 +63,6 @@ jobs:
|
|||||||
os: ubuntu-22.04
|
os: ubuntu-22.04
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
cflags: '-Wnonnull'
|
cflags: '-Wnonnull'
|
||||||
configureopts: '--with-readline=yes'
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -75,7 +73,7 @@ jobs:
|
|||||||
sudo apt-get install -y bison comerr-dev flex doxygen
|
sudo apt-get install -y bison comerr-dev flex doxygen
|
||||||
sudo apt-get install -y libcap-ng-dev libdb-dev libedit-dev libjson-perl
|
sudo apt-get install -y libcap-ng-dev libdb-dev libedit-dev libjson-perl
|
||||||
sudo apt-get install -y libldap2-dev libncurses5-dev libperl4-corelibs-perl
|
sudo apt-get install -y libldap2-dev libncurses5-dev libperl4-corelibs-perl
|
||||||
sudo apt-get install -y libsqlite3-dev libkeyutils-dev libreadline-dev pkg-config python3
|
sudo apt-get install -y libsqlite3-dev libkeyutils-dev pkg-config python3
|
||||||
sudo apt-get install -y ss-dev texinfo unzip netbase keyutils ldap-utils
|
sudo apt-get install -y ss-dev texinfo unzip netbase keyutils ldap-utils
|
||||||
sudo apt-get install -y gdb apport curl libmicrohttpd-dev jq valgrind
|
sudo apt-get install -y gdb apport curl libmicrohttpd-dev jq valgrind
|
||||||
# Temporary workaround for:
|
# Temporary workaround for:
|
||||||
@@ -85,7 +83,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
CONFIGURE_OPTS: ${{ matrix.configureopts }}
|
|
||||||
run: |
|
run: |
|
||||||
/bin/sh ./autogen.sh
|
/bin/sh ./autogen.sh
|
||||||
mkdir build
|
mkdir build
|
||||||
@@ -93,7 +90,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 40
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
@@ -111,27 +107,6 @@ jobs:
|
|||||||
make DESTDIR=/tmp/h5l install
|
make DESTDIR=/tmp/h5l install
|
||||||
cd /tmp/h5l
|
cd /tmp/h5l
|
||||||
tar czf $HOME/heimdal-install-linux-${{ matrix.compiler }}.tgz .
|
tar czf $HOME/heimdal-install-linux-${{ matrix.compiler }}.tgz .
|
||||||
- name: Interrupted/timed out test diagnostics
|
|
||||||
if: ${{ cancelled() || failure() }}
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
# Show any test-related processes still running
|
|
||||||
ps auxww | grep -E 'kdc|test_context|kinit|kadmin|check-' | grep -v grep || true
|
|
||||||
# Show who's on the test port
|
|
||||||
ss -tlnp sport = :49188 || true
|
|
||||||
# Show the newest .log file (the one likely interrupted)
|
|
||||||
newest=$(find build/tests -name '*.log' -newer build/tests/gss/Makefile -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
|
||||||
if [ -n "$newest" ]; then
|
|
||||||
echo "=== Newest test log: $newest ==="
|
|
||||||
cat "$newest"
|
|
||||||
fi
|
|
||||||
# Also show KDC messages.log if any exist
|
|
||||||
for f in build/tests/gss/messages.log build/tests/kdc/messages.log; do
|
|
||||||
if [ -f "$f" ]; then
|
|
||||||
echo "=== $f ==="
|
|
||||||
tail -100 "$f"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
- name: Core dump stacks
|
- name: Core dump stacks
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
run: |
|
run: |
|
||||||
@@ -172,75 +147,3 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: Test Logs (${{ matrix.name }})
|
name: Test Logs (${{ matrix.name }})
|
||||||
path: '~/logs-linux-${{ matrix.compiler }}.tgz'
|
path: '~/logs-linux-${{ matrix.compiler }}.tgz'
|
||||||
|
|
||||||
linux-i386:
|
|
||||||
name: linux-i386 (${{ matrix.name }})
|
|
||||||
# Run if no [only X] tag, or if [only linux] is present (check both push commits and PR titles)
|
|
||||||
if: >-
|
|
||||||
(!contains(github.event.head_commit.message, '[only ') &&
|
|
||||||
!contains(github.event.pull_request.title, '[only ')) ||
|
|
||||||
contains(github.event.head_commit.message, '[only linux]') ||
|
|
||||||
contains(github.event.pull_request.title, '[only linux]')
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- name: time32
|
|
||||||
image: i386/debian:bookworm
|
|
||||||
year2038_configure: ""
|
|
||||||
time_t_size: 4
|
|
||||||
- name: year2038
|
|
||||||
image: i386/debian:trixie
|
|
||||||
year2038_configure: --enable-year2038
|
|
||||||
time_t_size: 8
|
|
||||||
steps:
|
|
||||||
- name: Clone repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Build and test on Debian i386
|
|
||||||
run: |
|
|
||||||
docker run --security-opt seccomp=unconfined --platform linux/386 --rm \
|
|
||||||
-v "$PWD:/src:ro" \
|
|
||||||
-e YEAR2038_CONFIGURE="${{ matrix.year2038_configure }}" \
|
|
||||||
-e EXPECT_TIME_T_SIZE="${{ matrix.time_t_size }}" \
|
|
||||||
${{ matrix.image }} \
|
|
||||||
/bin/bash -euxc '
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
apt-get update -qq
|
|
||||||
apt-get install -y --no-install-recommends \
|
|
||||||
autoconf automake bison build-essential ca-certificates \
|
|
||||||
comerr-dev curl doxygen flex gdb git iproute2 jq keyutils \
|
|
||||||
ldap-utils libcap-ng-dev libdb-dev libedit-dev libjson-perl \
|
|
||||||
libkeyutils-dev libldap2-dev liblmdb-dev libmicrohttpd-dev libncurses5-dev \
|
|
||||||
libperl4-corelibs-perl libreadline-dev libsqlite3-dev libssl-dev \
|
|
||||||
libtool make netbase pkg-config procps python3 ss-dev tar \
|
|
||||||
texinfo unzip valgrind xz-utils
|
|
||||||
|
|
||||||
cp -a /src /tmp/heimdal-src
|
|
||||||
git config --global --add safe.directory /tmp/heimdal-src
|
|
||||||
cd /tmp/heimdal-src
|
|
||||||
/bin/sh ./autogen.sh
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
../configure --srcdir=`dirname "$PWD"` \
|
|
||||||
--enable-maintainer-mode \
|
|
||||||
--enable-developer \
|
|
||||||
${YEAR2038_CONFIGURE} \
|
|
||||||
--with-ldap \
|
|
||||||
--with-readline=yes \
|
|
||||||
--with-db-type-preference=lmdb \
|
|
||||||
--prefix=/tmp/heimdal-i386-inst \
|
|
||||||
CFLAGS="-Wnonnull -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
|
||||||
printf "%s\n" \
|
|
||||||
"#include \"include/config.h\"" \
|
|
||||||
"#include <stdio.h>" \
|
|
||||||
"#include <time.h>" \
|
|
||||||
"int main(void) { unsigned long s = sizeof(time_t); printf(\"sizeof(time_t)=%lu\n\", s); return s == EXPECT_TIME_T_SIZE ? 0 : 1; }" \
|
|
||||||
> check-time-t.c
|
|
||||||
cc -I. -I.. -DEXPECT_TIME_T_SIZE="$EXPECT_TIME_T_SIZE" -o check-time-t check-time-t.c
|
|
||||||
./check-time-t
|
|
||||||
make -j4
|
|
||||||
make -C lib/asn1 check
|
|
||||||
make -C lib/hx509 check TESTS=test_cert_binary
|
|
||||||
make DESTDIR=/tmp/heimdal-i386-root install
|
|
||||||
'
|
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ jobs:
|
|||||||
- name: osx-clang
|
- name: osx-clang
|
||||||
os: macos-latest
|
os: macos-latest
|
||||||
compiler: clang
|
compiler: clang
|
||||||
configureopts: '--with-libedit=yes'
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: |
|
run: |
|
||||||
@@ -94,7 +93,6 @@ jobs:
|
|||||||
# with:
|
# with:
|
||||||
# limit-access-to-actor: true
|
# limit-access-to-actor: true
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 25
|
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
@@ -107,27 +105,6 @@ jobs:
|
|||||||
sudo lsof -nP -i:49188 || true
|
sudo lsof -nP -i:49188 || true
|
||||||
cd build
|
cd build
|
||||||
make check
|
make check
|
||||||
- name: Interrupted/timed out test diagnostics
|
|
||||||
if: ${{ cancelled() || failure() }}
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
# Show any test-related processes still running
|
|
||||||
ps auxww | grep -E 'kdc|test_context|kinit|kadmin|check-' | grep -v grep || true
|
|
||||||
# Show who's on the test port
|
|
||||||
sudo lsof -nP -i:49188 || true
|
|
||||||
# Show the newest .log file (the one likely interrupted)
|
|
||||||
newest=$(find build/tests -name '*.log' -newer build/tests/gss/Makefile -print0 2>/dev/null | xargs -0 stat -f '%m %N' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
|
||||||
if [ -n "$newest" ]; then
|
|
||||||
echo "=== Newest test log: $newest ==="
|
|
||||||
cat "$newest"
|
|
||||||
fi
|
|
||||||
# Also show KDC messages.log if any exist
|
|
||||||
for f in build/tests/gss/messages.log build/tests/kdc/messages.log; do
|
|
||||||
if [ -f "$f" ]; then
|
|
||||||
echo "=== $f ==="
|
|
||||||
tail -100 "$f"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: |
|
run: |
|
||||||
cd build || true
|
cd build || true
|
||||||
@@ -135,7 +112,6 @@ jobs:
|
|||||||
cd /tmp/h5l
|
cd /tmp/h5l
|
||||||
tar czf $HOME/heimdal-install-osx.tgz .
|
tar czf $HOME/heimdal-install-osx.tgz .
|
||||||
- name: Test logs
|
- name: Test logs
|
||||||
if: ${{ always() }}
|
|
||||||
run: |
|
run: |
|
||||||
find build -depth -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/' | cpio -o > $HOME/logs-osx.cpio
|
find build -depth -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/' | cpio -o > $HOME/logs-osx.cpio
|
||||||
find build -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/'|xargs cat
|
find build -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/'|xargs cat
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ jobs:
|
|||||||
cd build
|
cd build
|
||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
||||||
ulimit -c unlimited
|
ulimit -c unlimited
|
||||||
# We don't want to scan-build SQLite3 because ETOOSLOW
|
# We don't want to scan-build libedit nor SQLite3 because ETOOSLOW
|
||||||
|
(cd lib/libedit && make -j4)
|
||||||
(cd lib/sqlite && make -j4)
|
(cd lib/sqlite && make -j4)
|
||||||
scan-build --keep-going make -j4
|
scan-build --keep-going make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 40
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --enable-dynamic --disable-static --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations" LDFLAGS="${{ matrix.ldflags }}"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --enable-dynamic --disable-static --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations" LDFLAGS="${{ matrix.ldflags }}"
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 80
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-gdwarf-4 -g -ggdb3 -O0 -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-gdwarf-4 -g -ggdb3 -O0 -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 120
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ jobs:
|
|||||||
)
|
)
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 20
|
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
set "PATH=%PATH%;C:\msys64\usr\bin"
|
set "PATH=%PATH%;C:\msys64\usr\bin"
|
||||||
|
|||||||
+26
-3
@@ -64,6 +64,32 @@ asn1_*_asn1.c
|
|||||||
/tmp.h
|
/tmp.h
|
||||||
/ylwrap
|
/ylwrap
|
||||||
|
|
||||||
|
/lib/libedit/aclocal.m4
|
||||||
|
/lib/libedit/autom4te.cache
|
||||||
|
/lib/libedit/compile
|
||||||
|
/lib/libedit/config.guess
|
||||||
|
/lib/libedit/config.h
|
||||||
|
/lib/libedit/config.log
|
||||||
|
/lib/libedit/config.status
|
||||||
|
/lib/libedit/config.sub
|
||||||
|
/lib/libedit/configure
|
||||||
|
/lib/libedit/depcomp
|
||||||
|
/lib/libedit/install-sh
|
||||||
|
/lib/libedit/libtool
|
||||||
|
/lib/libedit/ltmain.sh
|
||||||
|
/lib/libedit/missing
|
||||||
|
/lib/libedit/setupbuild.cmd
|
||||||
|
/lib/libedit/ylwrap
|
||||||
|
/lib/libedit/src/common.h
|
||||||
|
/lib/libedit/src/emacs.h
|
||||||
|
/lib/libedit/src/fcns.c
|
||||||
|
/lib/libedit/src/fcns.h
|
||||||
|
/lib/libedit/src/func.h
|
||||||
|
/lib/libedit/src/help.c
|
||||||
|
/lib/libedit/src/help.h
|
||||||
|
/lib/libedit/src/vi.h
|
||||||
|
/lib/libedit/stamp-h1
|
||||||
|
|
||||||
# Files in subdirectories.
|
# Files in subdirectories.
|
||||||
|
|
||||||
/admin/ktutil
|
/admin/ktutil
|
||||||
@@ -694,6 +720,3 @@ asn1_*_asn1.c
|
|||||||
/tools/krb5-gssapi.pc
|
/tools/krb5-gssapi.pc
|
||||||
/tools/krb5.pc
|
/tools/krb5.pc
|
||||||
/tools/krb5-config
|
/tools/krb5-config
|
||||||
|
|
||||||
result
|
|
||||||
result-*
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Folder-specific settings
|
||||||
|
//
|
||||||
|
// For a full list of overridable settings, and general information on folder-specific settings,
|
||||||
|
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
|
||||||
|
{
|
||||||
|
"tab_size": 8,
|
||||||
|
"hard_tabs": false
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ Release Notes - Heimdal - Version Heimdal 8.0 (future)
|
|||||||
- Errors found by the LLVM scan-build static analyzer.
|
- Errors found by the LLVM scan-build static analyzer.
|
||||||
- Errors found by the valgrind memory debugger.
|
- Errors found by the valgrind memory debugger.
|
||||||
- Fix out-of-tree SQLite3 ccache permissions / umask issues.
|
- Fix out-of-tree SQLite3 ccache permissions / umask issues.
|
||||||
- Clamp far-future ASN.1 times on 32-bit time_t platforms instead of wrapping.
|
|
||||||
- iprop bugs, race conditions, and performance
|
- iprop bugs, race conditions, and performance
|
||||||
- Many misc. bugs
|
- Many misc. bugs
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
||||||
[](https://coveralls.io/github/heimdal/heimdal?branch=master)
|
|
||||||
|
|
||||||
Heimdal
|
Heimdal
|
||||||
=======
|
=======
|
||||||
@@ -34,4 +33,3 @@ Build Status
|
|||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
||||||
[](https://coveralls.io/github/heimdal/heimdal?branch=master)
|
|
||||||
|
|||||||
+19
-42
@@ -43,9 +43,6 @@ kt_rename(struct rename_options *opt, int argc, char **argv)
|
|||||||
krb5_keytab keytab;
|
krb5_keytab keytab;
|
||||||
krb5_kt_cursor cursor;
|
krb5_kt_cursor cursor;
|
||||||
krb5_principal from_princ, to_princ;
|
krb5_principal from_princ, to_princ;
|
||||||
krb5_keytab_entry *entries = NULL;
|
|
||||||
size_t num_entries = 0;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
ret = krb5_parse_name(context, argv[0], &from_princ);
|
ret = krb5_parse_name(context, argv[0], &from_princ);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
@@ -66,14 +63,6 @@ kt_rename(struct rename_options *opt, int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Collect matching entries first, then close the cursor before
|
|
||||||
* adding/removing. We must not call krb5_kt_add_entry() or
|
|
||||||
* krb5_kt_remove_entry() while holding the seq_get cursor because
|
|
||||||
* the cursor holds a shared file lock and the add/remove operations
|
|
||||||
* need an exclusive lock -- with per-fd locking (BSD flock, OFD locks)
|
|
||||||
* this self-deadlocks.
|
|
||||||
*/
|
|
||||||
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
|
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
krb5_kt_close(context, keytab);
|
krb5_kt_close(context, keytab);
|
||||||
@@ -81,52 +70,40 @@ kt_rename(struct rename_options *opt, int argc, char **argv)
|
|||||||
krb5_free_principal(context, to_princ);
|
krb5_free_principal(context, to_princ);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
|
while(1) {
|
||||||
if(krb5_principal_compare(context, entry.principal, from_princ)) {
|
ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
|
||||||
krb5_keytab_entry *tmp;
|
if(ret != 0) {
|
||||||
|
if(ret != KRB5_CC_END && ret != KRB5_KT_END)
|
||||||
tmp = realloc(entries, (num_entries + 1) * sizeof(*entries));
|
krb5_warn(context, ret, "getting entry from keytab");
|
||||||
if (tmp == NULL) {
|
else
|
||||||
krb5_kt_free_entry(context, &entry);
|
ret = 0;
|
||||||
ret = krb5_enomem(context);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
entries = tmp;
|
if(krb5_principal_compare(context, entry.principal, from_princ)) {
|
||||||
krb5_free_principal(context, entry.principal);
|
krb5_free_principal(context, entry.principal);
|
||||||
entry.principal = NULL;
|
entry.principal = to_princ;
|
||||||
entries[num_entries++] = entry;
|
ret = krb5_kt_add_entry(context, keytab, &entry);
|
||||||
} else {
|
|
||||||
krb5_kt_free_entry(context, &entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(ret == KRB5_CC_END || ret == KRB5_KT_END)
|
|
||||||
ret = 0;
|
|
||||||
else if(ret)
|
|
||||||
krb5_warn(context, ret, "getting entry from keytab");
|
|
||||||
krb5_kt_end_seq_get(context, keytab, &cursor);
|
|
||||||
|
|
||||||
for (i = 0; ret == 0 && i < num_entries; i++) {
|
|
||||||
entries[i].principal = to_princ;
|
|
||||||
ret = krb5_kt_add_entry(context, keytab, &entries[i]);
|
|
||||||
if(ret) {
|
if(ret) {
|
||||||
|
entry.principal = NULL;
|
||||||
|
krb5_kt_free_entry(context, &entry);
|
||||||
krb5_warn(context, ret, "adding entry");
|
krb5_warn(context, ret, "adding entry");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (opt->delete_flag) {
|
if (opt->delete_flag) {
|
||||||
entries[i].principal = from_princ;
|
entry.principal = from_princ;
|
||||||
ret = krb5_kt_remove_entry(context, keytab, &entries[i]);
|
ret = krb5_kt_remove_entry(context, keytab, &entry);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
|
entry.principal = NULL;
|
||||||
|
krb5_kt_free_entry(context, &entry);
|
||||||
krb5_warn(context, ret, "removing entry");
|
krb5_warn(context, ret, "removing entry");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
entry.principal = NULL;
|
||||||
}
|
}
|
||||||
|
krb5_kt_free_entry(context, &entry);
|
||||||
for (i = 0; i < num_entries; i++) {
|
|
||||||
entries[i].principal = NULL;
|
|
||||||
krb5_kt_free_entry(context, &entries[i]);
|
|
||||||
}
|
}
|
||||||
free(entries);
|
krb5_kt_end_seq_get(context, keytab, &cursor);
|
||||||
|
|
||||||
krb5_free_principal(context, from_princ);
|
krb5_free_principal(context, from_princ);
|
||||||
krb5_free_principal(context, to_princ);
|
krb5_free_principal(context, to_princ);
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ man_MANS = bsearch.1
|
|||||||
|
|
||||||
EXTRA_DIST = NTMakefile $(man_MANS)
|
EXTRA_DIST = NTMakefile $(man_MANS)
|
||||||
|
|
||||||
LDADD = $(LIB_vers) $(LIB_heimbase) $(LIB_roken)
|
LDADD = $(LIB_roken) $(LIB_vers) $(LIB_heimbase)
|
||||||
|
|||||||
@@ -57,9 +57,6 @@ AS_IF([test "x$with_berkeley_db" != xno],
|
|||||||
db.h \
|
db.h \
|
||||||
])])
|
])])
|
||||||
|
|
||||||
dnl detect if compat db_185.h is present
|
|
||||||
AC_CHECK_HEADERS([db_185.h])
|
|
||||||
|
|
||||||
dnl db_create is used by db3 and db4 and db5 and db6
|
dnl db_create is used by db3 and db4 and db5 and db6
|
||||||
|
|
||||||
AC_FIND_FUNC_NO_LIBS(db_create, [$dbheader] db-6 db-5 db4 db3 db, [
|
AC_FIND_FUNC_NO_LIBS(db_create, [$dbheader] db-6 db-5 db4 db3 db, [
|
||||||
|
|||||||
+9
-69
@@ -9,80 +9,20 @@ AC_DEFUN([KRB_READLINE],[
|
|||||||
|
|
||||||
dnl readline
|
dnl readline
|
||||||
|
|
||||||
readline_requested="${with_readline-unset}"
|
ac_foo=no
|
||||||
libedit_requested="${with_libedit-unset}"
|
build_editline=no
|
||||||
have_readline=no
|
|
||||||
|
|
||||||
rk_TEST_PACKAGE(readline,
|
|
||||||
[#include <stdio.h>
|
|
||||||
#if defined(HAVE_READLINE_READLINE_H)
|
|
||||||
#include <readline/readline.h>
|
|
||||||
#elif defined(HAVE_READLINE_H)
|
|
||||||
#include <readline.h>
|
|
||||||
#endif
|
|
||||||
],-lreadline,[$LIB_tgetent],,[READLINE],, [readline.h readline/readline.h])
|
|
||||||
|
|
||||||
rk_TEST_PACKAGE(libedit,
|
|
||||||
[#include <stdio.h>
|
|
||||||
#if defined(HAVE_EDITLINE_READLINE_H)
|
|
||||||
#include <editline/readline.h>
|
|
||||||
#elif defined(HAVE_READLINE_READLINE_H)
|
|
||||||
#include <readline/readline.h>
|
|
||||||
#elif defined(HAVE_READLINE_H)
|
|
||||||
#include <readline.h>
|
|
||||||
#endif
|
|
||||||
],-ledit,[$LIB_tgetent],,[READLINE],,
|
|
||||||
[readline.h readline/readline.h editline/readline.h])
|
|
||||||
|
|
||||||
if test "$with_readline" = yes; then
|
if test "$with_readline" = yes; then
|
||||||
have_readline=yes
|
:
|
||||||
elif test "$with_libedit" = yes; then
|
elif test "$with_libedit" = yes; then
|
||||||
INCLUDE_readline="${INCLUDE_libedit}"
|
|
||||||
LIB_readline="${LIB_libedit}"
|
LIB_readline="${LIB_libedit}"
|
||||||
have_readline=yes
|
elif test "$ac_cv_func_readline" = yes; then
|
||||||
elif test "$readline_requested" != no; then
|
:
|
||||||
rk_readline_header=no
|
else
|
||||||
AC_CHECK_HEADERS([readline/readline.h readline.h],
|
build_libedit=yes
|
||||||
[rk_readline_header=yes])
|
LIB_readline="\$(top_builddir)/lib/libedit/src/libheimedit.la \$(LIB_tgetent)"
|
||||||
if test "$rk_readline_header" = yes; then
|
|
||||||
AC_CHECK_LIB(readline, readline, [
|
|
||||||
LIB_readline="-lreadline"
|
|
||||||
if test "x$LIB_tgetent" != x; then
|
|
||||||
LIB_readline="$LIB_readline $LIB_tgetent"
|
|
||||||
fi
|
fi
|
||||||
have_readline=yes
|
AM_CONDITIONAL(LIBEDIT, test "$build_libedit" = yes)
|
||||||
with_readline=yes
|
|
||||||
], [], [$LIB_tgetent])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$have_readline" != yes && test "$libedit_requested" != no; then
|
|
||||||
rk_libedit_header=no
|
|
||||||
AC_CHECK_HEADERS([editline/readline.h readline/readline.h readline.h],
|
|
||||||
[rk_libedit_header=yes])
|
|
||||||
if test "$rk_libedit_header" = yes; then
|
|
||||||
AC_CHECK_LIB(edit, readline, [
|
|
||||||
LIB_readline="-ledit"
|
|
||||||
if test "x$LIB_tgetent" != x; then
|
|
||||||
LIB_readline="$LIB_readline $LIB_tgetent"
|
|
||||||
fi
|
|
||||||
have_readline=yes
|
|
||||||
with_libedit=yes
|
|
||||||
], [], [$LIB_tgetent])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$have_readline" = yes; then
|
|
||||||
AC_DEFINE(HAVE_READLINE, 1,
|
AC_DEFINE(HAVE_READLINE, 1,
|
||||||
[Define if you have a readline compatible library.])dnl
|
[Define if you have a readline compatible library.])dnl
|
||||||
AC_DEFINE(READLINE, 1, [Define if you have the readline package.])dnl
|
|
||||||
else
|
|
||||||
INCLUDE_readline=
|
|
||||||
LIB_readline=
|
|
||||||
AC_MSG_NOTICE([readline/libedit not found; command line editing disabled])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_SUBST(INCLUDE_readline)
|
|
||||||
AC_SUBST(LIB_readline)
|
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -19,10 +19,4 @@ if test "$enable_largefile" != no; then
|
|||||||
[CPPFLAGS="$CPPFLAGS $ac_cv_sys_largefile_opts"])
|
[CPPFLAGS="$CPPFLAGS $ac_cv_sys_largefile_opts"])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if test "$enable_year2038" != no; then
|
|
||||||
if test -n "$ac_cv_sys_year2038_opts"; then
|
|
||||||
AS_CASE([$ac_cv_sys_year2038_opts],[-D_TIME_BITS=*|-D__MINGW_USE_VC2005_COMPAT],
|
|
||||||
[CPPFLAGS="$CPPFLAGS $ac_cv_sys_year2038_opts"])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
])
|
])
|
||||||
|
|||||||
+1
-2
@@ -192,6 +192,7 @@ AC_CHECK_FUNCS([ \
|
|||||||
mkdtemp \
|
mkdtemp \
|
||||||
mkostemp \
|
mkostemp \
|
||||||
on_exit \
|
on_exit \
|
||||||
|
poll \
|
||||||
random \
|
random \
|
||||||
secure_getenv \
|
secure_getenv \
|
||||||
setprogname \
|
setprogname \
|
||||||
@@ -359,8 +360,6 @@ AC_BROKEN([ \
|
|||||||
mergesort \
|
mergesort \
|
||||||
mergesort_r \
|
mergesort_r \
|
||||||
mkstemp \
|
mkstemp \
|
||||||
poll \
|
|
||||||
pread \
|
|
||||||
putenv \
|
putenv \
|
||||||
rcmd \
|
rcmd \
|
||||||
readv \
|
readv \
|
||||||
|
|||||||
+4
-4
@@ -24,8 +24,8 @@ AC_ARG_WITH($1-config,
|
|||||||
AS_HELP_STRING([--with-$1-config=path],[config program for $1]))
|
AS_HELP_STRING([--with-$1-config=path],[config program for $1]))
|
||||||
|
|
||||||
m4_ifval([$6],
|
m4_ifval([$6],
|
||||||
[m4_define([rk_pkgname], [$6])],
|
m4_define([rk_pkgname], $6),
|
||||||
[m4_define([rk_pkgname], [AS_TR_CPP($1)])])
|
m4_define([rk_pkgname], AS_TR_CPP($1)))
|
||||||
|
|
||||||
AC_MSG_CHECKING(for $1)
|
AC_MSG_CHECKING(for $1)
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ if test "$with_$1" != no; then
|
|||||||
if test "$[]$1_cflags" -a "$[]$1_libs"; then
|
if test "$[]$1_cflags" -a "$[]$1_libs"; then
|
||||||
CFLAGS="$[]$1_cflags $save_CFLAGS"
|
CFLAGS="$[]$1_cflags $save_CFLAGS"
|
||||||
LIBS="$[]$1_libs $save_LIBS"
|
LIBS="$[]$1_libs $save_LIBS"
|
||||||
m4_ifval([$8],[AC_CHECK_HEADERS([$8])])
|
m4_ifval([$8],[AC_CHECK_HEADERS([[$8]])])
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[
|
||||||
INCLUDE_$1="$[]$1_cflags"
|
INCLUDE_$1="$[]$1_cflags"
|
||||||
LIB_$1="$[]$1_libs"
|
LIB_$1="$[]$1_libs"
|
||||||
@@ -102,7 +102,7 @@ if test "$with_$1" != no; then
|
|||||||
ires= lres=
|
ires= lres=
|
||||||
for i in $header_dirs; do
|
for i in $header_dirs; do
|
||||||
CFLAGS="-I$i $save_CFLAGS"
|
CFLAGS="-I$i $save_CFLAGS"
|
||||||
m4_ifval([$8],[AC_CHECK_HEADERS([$8])])
|
m4_ifval([$8],[AC_CHECK_HEADERS([[$8]])])
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[ires=$i;break])
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[ires=$i;break])
|
||||||
done
|
done
|
||||||
for i in $lib_dirs; do
|
for i in $lib_dirs; do
|
||||||
|
|||||||
+22
-16
@@ -196,22 +196,6 @@ AM_CONDITIONAL([HAVE_CAPNG], [test "$with_capng" != "no"])
|
|||||||
AC_SUBST([CAPNG_CFLAGS])
|
AC_SUBST([CAPNG_CFLAGS])
|
||||||
AC_SUBST([CAPNG_LIBS])
|
AC_SUBST([CAPNG_LIBS])
|
||||||
|
|
||||||
dnl libsystemd
|
|
||||||
AC_ARG_WITH([systemd],
|
|
||||||
AC_HELP_STRING([--with-systemd], [use libsystemd for sd_notify service notifications @<:@default=check@:>@]),
|
|
||||||
[],
|
|
||||||
[with_systemd=check])
|
|
||||||
if test "$with_systemd" != "no"; then
|
|
||||||
PKG_CHECK_MODULES([SYSTEMD], [libsystemd],
|
|
||||||
[with_systemd=yes],[with_systemd=no])
|
|
||||||
fi
|
|
||||||
if test "$with_systemd" = "yes"; then
|
|
||||||
AC_DEFINE_UNQUOTED([HAVE_SYSTEMD], 1, [whether libsystemd is available for sd_notify])
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL([HAVE_SYSTEMD], [test "$with_systemd" != "no"])
|
|
||||||
AC_SUBST([SYSTEMD_CFLAGS])
|
|
||||||
AC_SUBST([SYSTEMD_LIBS])
|
|
||||||
|
|
||||||
dnl mitdb
|
dnl mitdb
|
||||||
AC_ARG_WITH([mitdb],
|
AC_ARG_WITH([mitdb],
|
||||||
AC_HELP_STRING([--with-mitdb], [Path to MIT Kerberos DB include header and shared object]),
|
AC_HELP_STRING([--with-mitdb], [Path to MIT Kerberos DB include header and shared object]),
|
||||||
@@ -398,6 +382,28 @@ AC_SUBST(ENABLE_AFS_STRING_TO_KEY)dnl
|
|||||||
|
|
||||||
rk_CHECK_MAN
|
rk_CHECK_MAN
|
||||||
|
|
||||||
|
rk_TEST_PACKAGE(readline,
|
||||||
|
[#include <stdio.h>
|
||||||
|
#if defined(HAVE_READLINE_READLINE_H)
|
||||||
|
#include <readline/readline.h>
|
||||||
|
#elif defined(HAVE_READLINE_H)
|
||||||
|
#include <readline.h>
|
||||||
|
#endif
|
||||||
|
],-lreadline,,, READLINE,, [readline.h readline/readline.h])
|
||||||
|
|
||||||
|
rk_TEST_PACKAGE(libedit,
|
||||||
|
[#include <stdio.h>
|
||||||
|
#if defined(HAVE_READLINE_READLINE_H)
|
||||||
|
#include <readline/readline.h>
|
||||||
|
#elif defined(HAVE_READLINE_H)
|
||||||
|
#include <readline.h>
|
||||||
|
#elif defined(HAVE_EDITLINE_READLINE_H)
|
||||||
|
#include <editline/readline.h>
|
||||||
|
#endif
|
||||||
|
],-ledit,,, READLINE,, [readline.h readline/readline.h editline/readline.h])
|
||||||
|
|
||||||
|
AC_CONFIG_SUBDIRS([lib/libedit])
|
||||||
|
|
||||||
KRB_C_BIGENDIAN
|
KRB_C_BIGENDIAN
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ The @code{popper} was also a Berkeley program initially.
|
|||||||
Some of the functions in @file{libroken} also come from Berkeley by way
|
Some of the functions in @file{libroken} also come from Berkeley by way
|
||||||
of NetBSD/FreeBSD.
|
of NetBSD/FreeBSD.
|
||||||
|
|
||||||
|
@code{editline} was written by Simmule Turner and Rich Salz. Heimdal
|
||||||
|
contains a modifed copy.
|
||||||
|
|
||||||
The @code{getifaddrs} implementation for Linux was written by Hideaki
|
The @code{getifaddrs} implementation for Linux was written by Hideaki
|
||||||
YOSHIFUJI for the Usagi project.
|
YOSHIFUJI for the Usagi project.
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,48 @@ SUCH DAMAGE.
|
|||||||
@end verbatim
|
@end verbatim
|
||||||
@copynext
|
@copynext
|
||||||
|
|
||||||
|
@heading The Regents of the University of California.
|
||||||
|
|
||||||
|
libedit
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
Copyright (c) 1992, 1993
|
||||||
|
The Regents of the University of California. All rights reserved.
|
||||||
|
|
||||||
|
This code is derived from software contributed to Berkeley by
|
||||||
|
Christos Zoulas of Cornell University.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the University nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
@end verbatim
|
||||||
|
@copynext
|
||||||
|
|
||||||
|
@copynext
|
||||||
|
|
||||||
@heading Doug Rabson
|
@heading Doug Rabson
|
||||||
|
|
||||||
GSS-API mechglue layer.
|
GSS-API mechglue layer.
|
||||||
|
|||||||
Generated
+3
-3
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770380644,
|
"lastModified": 1742800061,
|
||||||
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
|
"narHash": "sha256-oDJGK1UMArK52vcW9S5S2apeec4rbfNELgc50LqiPNs=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "ae67888ff7ef9dff69b3cf0cc0fbfbcd3a722abe",
|
"rev": "1750f3c1c89488e2ffdd47cab9d05454dddfb734",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -22,26 +22,13 @@
|
|||||||
default = pkgs.callPackage ./nix/shell.nix { };
|
default = pkgs.callPackage ./nix/shell.nix { };
|
||||||
});
|
});
|
||||||
|
|
||||||
packages = forAllSystems (system: pkgs: let
|
packages = forAllSystems (system: pkgs: with pkgs; {
|
||||||
src = lib.fileset.toSource {
|
|
||||||
root = ./.;
|
|
||||||
fileset = lib.fileset.difference ./. (lib.fileset.unions [
|
|
||||||
./.github
|
|
||||||
./.gitignore
|
|
||||||
./flake.nix
|
|
||||||
./flake.lock
|
|
||||||
./nix
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
default = self.packages.${system}.heimdal;
|
default = self.packages.${system}.heimdal;
|
||||||
|
|
||||||
src = pkgs.runCommand "heimdal-src" {} "ln -s ${src} \"$out\"";
|
heimdal = pkgs.callPackage ./nix/heimdal {
|
||||||
|
src = lib.cleanSource ./.;
|
||||||
heimdal = pkgs.callPackage ./nix/heimdal/package.nix {
|
|
||||||
inherit src;
|
|
||||||
inherit (pkgs.darwin.apple_sdk.frameworks) CoreFoundation Security SystemConfiguration;
|
inherit (pkgs.darwin.apple_sdk.frameworks) CoreFoundation Security SystemConfiguration;
|
||||||
autoreconfHook = pkgs.buildPackages.autoreconfHook271;
|
autoreconfHook = pkgs.buildPackages.autoreconfHook269;
|
||||||
};
|
};
|
||||||
|
|
||||||
nixosTest = pkgs.testers.runNixOSTest (import ./nix/nixosTest.nix { inherit nixpkgs; });
|
nixosTest = pkgs.testers.runNixOSTest (import ./nix/nixosTest.nix { inherit nixpkgs; });
|
||||||
|
|||||||
+2
-3
@@ -9,11 +9,9 @@ CHECK_LOCAL = no-check-local
|
|||||||
|
|
||||||
AM_CPPFLAGS += -DHOST=\"$(CANONICAL_HOST)\"
|
AM_CPPFLAGS += -DHOST=\"$(CANONICAL_HOST)\"
|
||||||
|
|
||||||
include_HEADERS = heim_threads.h
|
|
||||||
|
|
||||||
nodist_include_HEADERS = krb5-types.h
|
nodist_include_HEADERS = krb5-types.h
|
||||||
|
|
||||||
noinst_HEADERS = heimqueue.h crypto-headers.h
|
noinst_HEADERS = heimqueue.h heim_threads.h crypto-headers.h
|
||||||
|
|
||||||
EXTRA_DIST = NTMakefile krb5-types.cross config.h.w32
|
EXTRA_DIST = NTMakefile krb5-types.cross config.h.w32
|
||||||
|
|
||||||
@@ -50,6 +48,7 @@ CLEANFILES = \
|
|||||||
der.h \
|
der.h \
|
||||||
digest_asn1.h \
|
digest_asn1.h \
|
||||||
digest_template_asn1.h \
|
digest_template_asn1.h \
|
||||||
|
editline.h \
|
||||||
err.h \
|
err.h \
|
||||||
getarg.h \
|
getarg.h \
|
||||||
glob.h \
|
glob.h \
|
||||||
|
|||||||
+2
-5
@@ -54,7 +54,7 @@ kadmind_SOURCES = \
|
|||||||
|
|
||||||
add_random_users_SOURCES = add-random-users.c
|
add_random_users_SOURCES = add-random-users.c
|
||||||
|
|
||||||
test_util_SOURCES = test_util.c util.c random_password.c
|
test_util_SOURCES = test_util.c util.c
|
||||||
|
|
||||||
TESTS = test_util
|
TESTS = test_util
|
||||||
|
|
||||||
@@ -72,10 +72,7 @@ kadmind_LDADD = $(top_builddir)/lib/kadm5/libkadm5srv.la \
|
|||||||
../lib/gssapi/libgssapi.la \
|
../lib/gssapi/libgssapi.la \
|
||||||
$(LDADD_common) \
|
$(LDADD_common) \
|
||||||
$(LIB_pidfile) \
|
$(LIB_pidfile) \
|
||||||
$(LIB_dlopen) \
|
$(LIB_dlopen)
|
||||||
$(SYSTEMD_LIBS)
|
|
||||||
|
|
||||||
kadmind_CFLAGS = $(SYSTEMD_CFLAGS)
|
|
||||||
|
|
||||||
kadmin_LDADD = \
|
kadmin_LDADD = \
|
||||||
$(top_builddir)/lib/kadm5/libkadm5clnt.la \
|
$(top_builddir)/lib/kadm5/libkadm5clnt.la \
|
||||||
|
|||||||
@@ -68,6 +68,12 @@ do_ext_keytab(krb5_principal principal, void *data)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* Debug: record which principal was fetched and some context */
|
||||||
|
krb5_warnx(context, "do_ext_keytab: fetched principal %s mask=0x%x n_key_data=%d",
|
||||||
|
unparsed ? unparsed : "<unparsed>",
|
||||||
|
mask,
|
||||||
|
(int)princ.n_key_data);
|
||||||
|
|
||||||
if (!e->random_key_flag) {
|
if (!e->random_key_flag) {
|
||||||
if (princ.n_key_data == 0) {
|
if (princ.n_key_data == 0) {
|
||||||
krb5_warnx(context, "principal has no keys, or user lacks "
|
krb5_warnx(context, "principal has no keys, or user lacks "
|
||||||
@@ -111,6 +117,13 @@ do_ext_keytab(krb5_principal principal, void *data)
|
|||||||
keys[i].keyblock.keyvalue.data = kd->key_data_contents[0];
|
keys[i].keyblock.keyvalue.data = kd->key_data_contents[0];
|
||||||
keys[i].timestamp = time(NULL);
|
keys[i].timestamp = time(NULL);
|
||||||
n_k++;
|
n_k++;
|
||||||
|
|
||||||
|
/* Debug: log each key extracted (kvno/enctype) for the principal */
|
||||||
|
krb5_warnx(context, "do_ext_keytab: principal=%s key_index=%zu kvno=%d enctype=%d",
|
||||||
|
unparsed ? unparsed : "<unparsed>",
|
||||||
|
i,
|
||||||
|
keys[i].vno,
|
||||||
|
keys[i].keyblock.keytype);
|
||||||
}
|
}
|
||||||
} else if (e->random_key_flag) {
|
} else if (e->random_key_flag) {
|
||||||
ret = kadm5_randkey_principal_3(e->kadm_handle, principal, e->keep,
|
ret = kadm5_randkey_principal_3(e->kadm_handle, principal, e->keep,
|
||||||
@@ -208,6 +221,10 @@ ext_keytab(struct ext_keytab_options *opt, int argc, char **argv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Debug: record ext_keytab invocation details */
|
||||||
|
krb5_warnx(context, "ext_keytab: invoking foreach_principal for %zu principals, enctypes=%s",
|
||||||
|
(size_t)argc, enctypes ? enctypes : "<none>");
|
||||||
|
|
||||||
for(i = 0; i < argc; i++) {
|
for(i = 0; i < argc; i++) {
|
||||||
ret = foreach_principal(argv[i], do_ext_keytab, "ext", &data);
|
ret = foreach_principal(argv[i], do_ext_keytab, "ext", &data);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|||||||
+67
-2
@@ -488,12 +488,71 @@ do_get_entry(krb5_principal principal, void *data)
|
|||||||
e->upto--;
|
e->upto--;
|
||||||
|
|
||||||
memset(&princ, 0, sizeof(princ));
|
memset(&princ, 0, sizeof(princ));
|
||||||
|
|
||||||
|
/* Loud tracing: record which principal we are about to request from kadmind.
|
||||||
|
*
|
||||||
|
* Guard the unparse call: don't call into unparse with a NULL principal
|
||||||
|
* and only use the unparsed string if the call succeeds.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
char *want = NULL;
|
||||||
|
if (principal != NULL && krb5_unparse_name(context, principal, &want) == 0 && want != NULL) {
|
||||||
|
krb5_warnx(context, "kadmin:get: do_get_entry: requesting principal lookup for %s (mask=0x%x extra_mask=0x%x) (pid=%d)",
|
||||||
|
want, e->mask, e->extra_mask, (int)getpid());
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "kadmin:get: do_get_entry: requesting principal lookup for <unparsed> (mask=0x%x extra_mask=0x%x) (pid=%d)",
|
||||||
|
e->mask, e->extra_mask, (int)getpid());
|
||||||
|
}
|
||||||
|
free(want);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Always request the principal field so we can safely unparse/format
|
||||||
|
* the returned entry. Some callers request only TL_DATA (eg aliases),
|
||||||
|
* and the kadm5 backend may return successful results without filling
|
||||||
|
* the principal pointer which leads to crashes when we try to use it.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
uint32_t want_mask = e->mask | e->extra_mask | KADM5_PRINCIPAL;
|
||||||
ret = kadm5_get_principal(e->kadm_handle, principal,
|
ret = kadm5_get_principal(e->kadm_handle, principal,
|
||||||
&princ,
|
&princ,
|
||||||
e->mask | e->extra_mask);
|
want_mask);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
/* Success: log the fact we received a principal record and some basic info */
|
||||||
|
{
|
||||||
|
char *got = NULL;
|
||||||
|
if (krb5_unparse_name(context, princ.principal, &got) == 0) {
|
||||||
|
krb5_warnx(context, "kadmin:get: do_get_entry: kadm5_get_principal succeeded: principal=%s kvno=%d n_key_data=%d (pid=%d)",
|
||||||
|
got ? got : "<unparsed>",
|
||||||
|
princ.kvno,
|
||||||
|
princ.n_key_data,
|
||||||
|
(int)getpid());
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "kadmin:get: do_get_entry: kadm5_get_principal succeeded: <unparsed principal> kvno=%d n_key_data=%d (pid=%d)",
|
||||||
|
princ.kvno, princ.n_key_data, (int)getpid());
|
||||||
|
}
|
||||||
|
free(got);
|
||||||
|
}
|
||||||
|
|
||||||
(e->format)(e, &princ);
|
(e->format)(e, &princ);
|
||||||
kadm5_free_principal_ent(e->kadm_handle, &princ);
|
kadm5_free_principal_ent(e->kadm_handle, &princ);
|
||||||
|
} else {
|
||||||
|
/* Failure: log explicit error so we can trace failing lookups.
|
||||||
|
*
|
||||||
|
* Guard the unparse call similarly to above.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
char *want2 = NULL;
|
||||||
|
if (principal != NULL && krb5_unparse_name(context, principal, &want2) == 0 && want2 != NULL) {
|
||||||
|
krb5_warn(context, ret, "kadmin:get: do_get_entry: kadm5_get_principal(%s) failed (pid=%d)",
|
||||||
|
want2, (int)getpid());
|
||||||
|
} else {
|
||||||
|
krb5_warn(context, ret, "kadmin:get: do_get_entry: kadm5_get_principal(<unparsed>) failed (pid=%d)",
|
||||||
|
(int)getpid());
|
||||||
|
}
|
||||||
|
free(want2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e->n++;
|
e->n++;
|
||||||
@@ -627,8 +686,14 @@ getit(struct get_options *opt, const char *name, int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < argc; i++)
|
for(i = 0; i < argc; i++) {
|
||||||
|
/* Loud tracing: announce each foreach_principal invocation */
|
||||||
|
krb5_warnx(context, "kadmin:get: getit: invoking foreach_principal for arg[%d]=%s (call %d of %d) (pid=%d)",
|
||||||
|
i, argv[i] ? argv[i] : "<null>", i+1, argc, (int)getpid());
|
||||||
ret = foreach_principal(argv[i], do_get_entry, name, &data);
|
ret = foreach_principal(argv[i], do_get_entry, name, &data);
|
||||||
|
if (ret)
|
||||||
|
krb5_warn(context, ret, "kadmin:get: getit: foreach_principal(%s) returned error", argv[i] ? argv[i] : "<null>");
|
||||||
|
}
|
||||||
|
|
||||||
kadm5_destroy(data.kadm_handle);
|
kadm5_destroy(data.kadm_handle);
|
||||||
|
|
||||||
|
|||||||
+4
-65
@@ -35,11 +35,6 @@
|
|||||||
#ifdef HAVE_SYS_WAIT_H
|
#ifdef HAVE_SYS_WAIT_H
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
#include <systemd/sd-daemon.h>
|
|
||||||
/* how often (seconds) to refresh the sd_notify STATUS line while idle */
|
|
||||||
#define STATUS_INTERVAL 30
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int daemon_child;
|
extern int daemon_child;
|
||||||
|
|
||||||
@@ -208,52 +203,22 @@ wait_for_connection(krb5_context contextp,
|
|||||||
signal(SIGINT, terminate);
|
signal(SIGINT, terminate);
|
||||||
signal(SIGCHLD, sigchld);
|
signal(SIGCHLD, sigchld);
|
||||||
|
|
||||||
{
|
|
||||||
struct timeval *tmoutp = NULL;
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
unsigned long nconns = 0;
|
|
||||||
struct timeval tmout;
|
|
||||||
|
|
||||||
tmoutp = &tmout;
|
|
||||||
sd_notify(0, "READY=1");
|
|
||||||
sd_notifyf(0, "STATUS=Serving; %lu connection(s) accepted", nconns);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (term_flag == 0) {
|
while (term_flag == 0) {
|
||||||
read_set = orig_read_set;
|
read_set = orig_read_set;
|
||||||
#ifdef HAVE_SYSTEMD
|
e = select(max_fd + 1, &read_set, NULL, NULL, NULL);
|
||||||
tmout.tv_sec = STATUS_INTERVAL;
|
|
||||||
tmout.tv_usec = 0;
|
|
||||||
#endif
|
|
||||||
e = select(max_fd + 1, &read_set, NULL, NULL, tmoutp);
|
|
||||||
if(rk_IS_SOCKET_ERROR(e)) {
|
if(rk_IS_SOCKET_ERROR(e)) {
|
||||||
if(rk_SOCK_ERRNO != EINTR)
|
if(rk_SOCK_ERRNO != EINTR)
|
||||||
krb5_warn(contextp, rk_SOCK_ERRNO, "select");
|
krb5_warn(contextp, rk_SOCK_ERRNO, "select");
|
||||||
} else if(e == 0) {
|
} else if(e == 0)
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
/* select timed out: refresh our systemd status line */
|
|
||||||
sd_notifyf(0, "STATUS=Serving; %lu connection(s) accepted", nconns);
|
|
||||||
#else
|
|
||||||
krb5_warnx(contextp, "select returned 0");
|
krb5_warnx(contextp, "select returned 0");
|
||||||
#endif
|
else {
|
||||||
} else {
|
|
||||||
for(i = 0; i < num_socks; i++) {
|
for(i = 0; i < num_socks; i++) {
|
||||||
if(FD_ISSET(socks[i], &read_set)) {
|
if(FD_ISSET(socks[i], &read_set))
|
||||||
if(spawn_child(contextp, socks, num_socks, i) == 0)
|
if(spawn_child(contextp, socks, num_socks, i) == 0)
|
||||||
return;
|
return;
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
nconns++;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
sd_notify(0, "STOPPING=1");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
signal(SIGCHLD, SIG_IGN);
|
signal(SIGCHLD, SIG_IGN);
|
||||||
|
|
||||||
while ((waitpid(-1, &status, WNOHANG)) > 0)
|
while ((waitpid(-1, &status, WNOHANG)) > 0)
|
||||||
@@ -273,31 +238,6 @@ start_server(krb5_context contextp, const char *port_str)
|
|||||||
unsigned int num_socks = 0;
|
unsigned int num_socks = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
{
|
|
||||||
char **names = NULL;
|
|
||||||
int sd_n, j;
|
|
||||||
|
|
||||||
sd_n = sd_listen_fds_with_names(0, &names);
|
|
||||||
if (sd_n < 0)
|
|
||||||
krb5_err(contextp, 1, -sd_n, "sd_listen_fds_with_names");
|
|
||||||
if (sd_n > 0) {
|
|
||||||
socks = malloc(sd_n * sizeof(*socks));
|
|
||||||
if (socks == NULL)
|
|
||||||
krb5_err(contextp, 1, errno, "malloc");
|
|
||||||
for (j = 0; j < sd_n; j++) {
|
|
||||||
if (names != NULL && names[j] != NULL &&
|
|
||||||
strncmp(names[j], "kadmind", 7) == 0)
|
|
||||||
socks[num_socks++] = SD_LISTEN_FDS_START + j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (j = 0; names != NULL && names[j] != NULL; j++)
|
|
||||||
free(names[j]);
|
|
||||||
free(names);
|
|
||||||
}
|
|
||||||
#endif /* HAVE_SYSTEMD */
|
|
||||||
|
|
||||||
if (num_socks == 0) {
|
|
||||||
if (port_str == NULL)
|
if (port_str == NULL)
|
||||||
port_str = "+";
|
port_str = "+";
|
||||||
|
|
||||||
@@ -360,7 +300,6 @@ start_server(krb5_context contextp, const char *port_str)
|
|||||||
}
|
}
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(num_socks == 0)
|
if(num_socks == 0)
|
||||||
krb5_errx(contextp, 1, "no sockets to listen to - exiting");
|
krb5_errx(contextp, 1, "no sockets to listen to - exiting");
|
||||||
|
|
||||||
|
|||||||
+119
-18
@@ -32,30 +32,131 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kadmin_locl.h"
|
#include "kadmin_locl.h"
|
||||||
#include <base64.h>
|
|
||||||
|
|
||||||
#define RANDOM_PASSWORD_BYTES 12
|
/* This file defines some a function that generates a random password,
|
||||||
|
that can be used when creating a large amount of principals (such
|
||||||
|
as for a batch of students). Since this is a political matter, you
|
||||||
|
should think about how secure generated passwords has to be.
|
||||||
|
|
||||||
|
Both methods defined here will give you at least 55 bits of
|
||||||
|
entropy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* If you want OTP-style passwords, define OTP_STYLE */
|
||||||
|
|
||||||
|
#ifdef OTP_STYLE
|
||||||
|
#include <otp.h>
|
||||||
|
#else
|
||||||
|
static void generate_password(char **pw, int num_classes, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
random_password(char *pw, size_t len)
|
random_password(char *pw, size_t len)
|
||||||
{
|
{
|
||||||
unsigned char random[RANDOM_PASSWORD_BYTES];
|
#ifdef OTP_STYLE
|
||||||
char *password = NULL;
|
{
|
||||||
size_t password_len;
|
OtpKey newkey;
|
||||||
|
|
||||||
if (len == 0)
|
krb5_generate_random_block(&newkey, sizeof(newkey));
|
||||||
|
otp_print_stddict (newkey, pw, len);
|
||||||
|
strlwr(pw);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
char *pass;
|
||||||
|
generate_password(&pass, 3,
|
||||||
|
"abcdefghijklmnopqrstuvwxyz", 7,
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2,
|
||||||
|
"@$%&*()-+=:,/<>1234567890", 1);
|
||||||
|
strlcpy(pw, pass, len);
|
||||||
|
len = strlen(pass);
|
||||||
|
memset_s(pass, len, 0, len);
|
||||||
|
free(pass);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* some helper functions */
|
||||||
|
|
||||||
|
#ifndef OTP_STYLE
|
||||||
|
/* return a random value in range 0-127 */
|
||||||
|
static int
|
||||||
|
RND(unsigned char *key, int keylen, int *left)
|
||||||
|
{
|
||||||
|
if(*left == 0){
|
||||||
|
krb5_generate_random_block(key, keylen);
|
||||||
|
*left = keylen;
|
||||||
|
}
|
||||||
|
(*left)--;
|
||||||
|
return ((unsigned char*)key)[*left];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This a helper function that generates a random password with a
|
||||||
|
number of characters from a set of character classes.
|
||||||
|
|
||||||
|
If there are n classes, and the size of each class is Pi, and the
|
||||||
|
number of characters from each class is Ni, the number of possible
|
||||||
|
passwords are (given that the character classes are disjoint):
|
||||||
|
|
||||||
|
n n
|
||||||
|
----- / ---- \
|
||||||
|
| | Ni | \ |
|
||||||
|
| | Pi | \ Ni| !
|
||||||
|
| | ---- * | / |
|
||||||
|
| | Ni! | /___ |
|
||||||
|
i=1 \ i=1 /
|
||||||
|
|
||||||
|
Since it uses the RND function above, neither the size of each
|
||||||
|
class, nor the total length of the generated password should be
|
||||||
|
larger than 127 (without fixing RND).
|
||||||
|
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
generate_password(char **pw, int num_classes, ...)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
const char *str;
|
||||||
|
int len;
|
||||||
|
int freq;
|
||||||
|
} *classes;
|
||||||
|
va_list ap;
|
||||||
|
int len, i;
|
||||||
|
unsigned char rbuf[8]; /* random buffer */
|
||||||
|
int rleft = 0;
|
||||||
|
|
||||||
|
*pw = NULL;
|
||||||
|
|
||||||
|
classes = malloc(num_classes * sizeof(*classes));
|
||||||
|
if(classes == NULL)
|
||||||
return;
|
return;
|
||||||
|
va_start(ap, num_classes);
|
||||||
krb5_generate_random_block(random, sizeof(random));
|
len = 0;
|
||||||
if (rk_base64url_encode(random, sizeof(random), &password) < 0 ||
|
for(i = 0; i < num_classes; i++){
|
||||||
password == NULL) {
|
classes[i].str = va_arg(ap, const char*);
|
||||||
memset_s(random, sizeof(random), 0, sizeof(random));
|
classes[i].len = strlen(classes[i].str);
|
||||||
krb5_abortx(NULL, "Failed to encode random password");
|
classes[i].freq = va_arg(ap, int);
|
||||||
|
len += classes[i].freq;
|
||||||
}
|
}
|
||||||
|
va_end(ap);
|
||||||
password_len = strlen(password);
|
*pw = malloc(len + 1);
|
||||||
strlcpy(pw, password, len);
|
if(*pw == NULL) {
|
||||||
memset_s(random, sizeof(random), 0, sizeof(random));
|
free(classes);
|
||||||
memset_s(password, password_len, 0, password_len);
|
return;
|
||||||
free(password);
|
|
||||||
}
|
}
|
||||||
|
for(i = 0; i < len; i++) {
|
||||||
|
int j;
|
||||||
|
int x = RND(rbuf, sizeof(rbuf), &rleft) % (len - i);
|
||||||
|
int t = 0;
|
||||||
|
for(j = 0; j < num_classes; j++) {
|
||||||
|
if(x < t + classes[j].freq) {
|
||||||
|
(*pw)[i] = classes[j].str[RND(rbuf, sizeof(rbuf), &rleft)
|
||||||
|
% classes[j].len];
|
||||||
|
classes[j].freq--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t += classes[j].freq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*pw)[len] = '\0';
|
||||||
|
memset_s(rbuf, sizeof(rbuf), 0, sizeof(rbuf));
|
||||||
|
free(classes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -624,7 +624,31 @@ proc_get_principal(kadm5_server_context *contextp,
|
|||||||
if(ret)
|
if(ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
/* Loud tracing: log which client requested this GET and what principal is being looked up */
|
||||||
|
{
|
||||||
|
char *want = NULL;
|
||||||
|
(void) krb5_unparse_name(contextp->context, princ, &want);
|
||||||
|
krb5_warnx(contextp->context,
|
||||||
|
"proc_get_principal: received GET request for principal=%s mask=0x%x (pid=%d ppid=%d uid=%d)",
|
||||||
|
want ? want : "<unparsed>",
|
||||||
|
mask,
|
||||||
|
(int)getpid(),
|
||||||
|
(int)getppid(),
|
||||||
|
(int)getuid());
|
||||||
|
free(want);
|
||||||
|
}
|
||||||
|
|
||||||
ret = kadm5_get_principal(contextp, princ, &ent, mask);
|
ret = kadm5_get_principal(contextp, princ, &ent, mask);
|
||||||
|
if (ret) {
|
||||||
|
/* Extra log to make failures obvious at the call site */
|
||||||
|
char *want2 = NULL;
|
||||||
|
(void) krb5_unparse_name(contextp->context, princ, &want2);
|
||||||
|
krb5_warn(contextp->context, ret,
|
||||||
|
"proc_get_principal: kadm5_get_principal failed for principal=%s (pid=%d)",
|
||||||
|
want2 ? want2 : "<unparsed>",
|
||||||
|
(int)getpid());
|
||||||
|
free(want2);
|
||||||
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
krb5_warn(contextp->context, ret, "get principal principal");
|
krb5_warn(contextp->context, ret, "get principal principal");
|
||||||
|
|||||||
@@ -226,6 +226,8 @@ kadmind_dispatch_int(void *kadm_handlep, krb5_boolean initial,
|
|||||||
ret_sp = krb5_store_int32(rsp, KADM5_FAILURE);
|
ret_sp = krb5_store_int32(rsp, KADM5_FAILURE);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
/* Debug: record which client and numeric command we received */
|
||||||
|
krb5_warnx(contextp->context, "kadmind_dispatch: received request from client=%s cmd=%d", client, cmd);
|
||||||
|
|
||||||
switch(cmd){
|
switch(cmd){
|
||||||
case kadm_nop:{
|
case kadm_nop:{
|
||||||
@@ -268,6 +270,8 @@ kadmind_dispatch_int(void *kadm_handlep, krb5_boolean initial,
|
|||||||
mask |= KADM5_PRINCIPAL;
|
mask |= KADM5_PRINCIPAL;
|
||||||
krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name));
|
krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name));
|
||||||
krb5_warnx(contextp->context, "%s: %s %s", client, op, name);
|
krb5_warnx(contextp->context, "%s: %s %s", client, op, name);
|
||||||
|
/* Debug: include mask/keys_ok context so we can correlate admin requests to keytab lookups */
|
||||||
|
krb5_warnx(contextp->context, "kadmind_dispatch: GET invoked by %s for %s (mask=0x%x, keys_ok=%d)", client, name, mask, keys_ok);
|
||||||
|
|
||||||
/* If the caller doesn't have KADM5_PRIV_GET, we're done. */
|
/* If the caller doesn't have KADM5_PRIV_GET, we're done. */
|
||||||
ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_GET, princ);
|
ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_GET, princ);
|
||||||
@@ -307,6 +311,7 @@ kadmind_dispatch_int(void *kadm_handlep, krb5_boolean initial,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
krb5_warnx(contextp->context, "kadmind_dispatch: calling kadm5_get_principal for %s (mask=0x%x, keys_ok=%d)", name, mask, keys_ok);
|
||||||
ret = kadm5_get_principal(kadm_handlep, princ, &ent, mask);
|
ret = kadm5_get_principal(kadm_handlep, princ, &ent, mask);
|
||||||
ret_sp = krb5_store_int32(rsp, ret);
|
ret_sp = krb5_store_int32(rsp, ret);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
|||||||
+1
-44
@@ -68,49 +68,6 @@ test_time(void)
|
|||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
test_random_password(void)
|
|
||||||
{
|
|
||||||
static const char alphabet[] =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
||||||
char pw[128];
|
|
||||||
char small[5];
|
|
||||||
char zero[1] = { 'x' };
|
|
||||||
size_t i, j;
|
|
||||||
int errors = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 128; i++) {
|
|
||||||
random_password(pw, sizeof(pw));
|
|
||||||
if (strlen(pw) != 16) {
|
|
||||||
printf("wrong random password length: %lu\n",
|
|
||||||
(unsigned long)strlen(pw));
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
for (j = 0; pw[j] != '\0'; j++) {
|
|
||||||
if (strchr(alphabet, pw[j]) == NULL) {
|
|
||||||
printf("random password contains invalid byte: 0x%02x\n",
|
|
||||||
(unsigned char)pw[j]);
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
random_password(small, sizeof(small));
|
|
||||||
if (strlen(small) != sizeof(small) - 1) {
|
|
||||||
printf("wrong short random password length: %lu\n",
|
|
||||||
(unsigned long)strlen(small));
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
random_password(zero, 0);
|
|
||||||
if (zero[0] != 'x') {
|
|
||||||
printf("zero-length random password buffer was modified\n");
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
@@ -125,9 +82,9 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
ret += test_time();
|
ret += test_time();
|
||||||
ret += test_random_password();
|
|
||||||
|
|
||||||
krb5_free_context(context);
|
krb5_free_context(context);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -198,12 +198,12 @@ LDADD = $(top_builddir)/lib/hdb/libhdb.la \
|
|||||||
$(LIB_roken) \
|
$(LIB_roken) \
|
||||||
$(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB)
|
$(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB)
|
||||||
|
|
||||||
kdc_LDADD = libkdc.la $(LDADD) $(LIB_pidfile) $(CAPNG_LIBS) $(SYSTEMD_LIBS)
|
kdc_LDADD = libkdc.la $(LDADD) $(LIB_pidfile) $(CAPNG_LIBS)
|
||||||
|
|
||||||
if FRAMEWORK_SECURITY
|
if FRAMEWORK_SECURITY
|
||||||
kdc_LDFLAGS = -framework SystemConfiguration -framework CoreFoundation
|
kdc_LDFLAGS = -framework SystemConfiguration -framework CoreFoundation
|
||||||
endif
|
endif
|
||||||
kdc_CFLAGS = $(CAPNG_CFLAGS) $(SYSTEMD_CFLAGS)
|
kdc_CFLAGS = $(CAPNG_CFLAGS)
|
||||||
|
|
||||||
kdc_replay_LDADD = libkdc.la $(LDADD) $(LIB_pidfile)
|
kdc_replay_LDADD = libkdc.la $(LDADD) $(LIB_pidfile)
|
||||||
kdc_tester_LDADD = libkdc.la $(LDADD) $(LIB_pidfile) $(LIB_heimbase)
|
kdc_tester_LDADD = libkdc.la $(LDADD) $(LIB_pidfile) $(LIB_heimbase)
|
||||||
|
|||||||
@@ -33,10 +33,6 @@
|
|||||||
|
|
||||||
#include "kdc_locl.h"
|
#include "kdc_locl.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
#include <systemd/sd-daemon.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* a tuple describing on what to listen
|
* a tuple describing on what to listen
|
||||||
*/
|
*/
|
||||||
@@ -299,69 +295,6 @@ init_socket(krb5_context context,
|
|||||||
socket_set_keepalive(d->s, 1);
|
socket_set_keepalive(d->s, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
/*
|
|
||||||
* Allocate descriptors for the sockets handed to us via systemd socket
|
|
||||||
* activation whose FileDescriptorName is "kdc", and return then number of
|
|
||||||
* them (0 if we were not socket-activated).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
init_sockets_sd(krb5_context context,
|
|
||||||
krb5_kdc_configuration *config,
|
|
||||||
struct descr **desc)
|
|
||||||
{
|
|
||||||
char **names = NULL;
|
|
||||||
struct descr *d;
|
|
||||||
int n, i, num = 0;
|
|
||||||
|
|
||||||
n = sd_listen_fds_with_names(0, &names);
|
|
||||||
if (n < 0)
|
|
||||||
krb5_err(context, 1, -n, "sd_listen_fds_with_names");
|
|
||||||
if (n == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
d = malloc(n * sizeof(*d));
|
|
||||||
if (d == NULL)
|
|
||||||
krb5_errx(context, 1, "malloc(%lu) failed",
|
|
||||||
(unsigned long)n * sizeof(*d));
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
int fd = SD_LISTEN_FDS_START + i;
|
|
||||||
int type;
|
|
||||||
socklen_t tlen = sizeof(type);
|
|
||||||
|
|
||||||
if (names == NULL || names[i] == NULL ||
|
|
||||||
strncmp(names[i], "kdc", 3) != 0)
|
|
||||||
continue;
|
|
||||||
if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &tlen) < 0) {
|
|
||||||
krb5_warn(context, errno,
|
|
||||||
"getsockopt(SO_TYPE) on socket-activated fd %d", fd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
init_descr(&d[num]);
|
|
||||||
d[num].s = fd;
|
|
||||||
d[num].type = type;
|
|
||||||
socket_set_nonblocking(fd, 1);
|
|
||||||
kdc_log(context, config, 3, "listening on socket-activated fd %d (%s)",
|
|
||||||
fd, (type == SOCK_STREAM) ? "tcp" : "udp");
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; names != NULL && names[i] != NULL; i++)
|
|
||||||
free(names[i]);
|
|
||||||
free(names);
|
|
||||||
|
|
||||||
if (num == 0) {
|
|
||||||
free(d);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
reinit_descrs(d, num);
|
|
||||||
*desc = d;
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_SYSTEMD */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate descriptors for all the sockets that we should listen on
|
* Allocate descriptors for all the sockets that we should listen on
|
||||||
* and return the number of them.
|
* and return the number of them.
|
||||||
@@ -1258,11 +1191,6 @@ start_kdc(krb5_context context,
|
|||||||
socket_set_nonblocking(islive[1], 1);
|
socket_set_nonblocking(islive[1], 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ndescr = 0;
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
ndescr = init_sockets_sd(context, config, &d);
|
|
||||||
#endif
|
|
||||||
if (ndescr <= 0)
|
|
||||||
ndescr = init_sockets(context, config, &d);
|
ndescr = init_sockets(context, config, &d);
|
||||||
if(ndescr <= 0)
|
if(ndescr <= 0)
|
||||||
krb5_errx(context, 1, "No sockets!");
|
krb5_errx(context, 1, "No sockets!");
|
||||||
@@ -1281,11 +1209,6 @@ start_kdc(krb5_context context,
|
|||||||
|
|
||||||
roken_detach_finish(NULL, daemon_child);
|
roken_detach_finish(NULL, daemon_child);
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
sd_notify(0, "READY=1");
|
|
||||||
sd_notify(0, "STATUS=Serving requests");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_FORK
|
#ifdef HAVE_FORK
|
||||||
if (!testing_flag) {
|
if (!testing_flag) {
|
||||||
/* Note that we might never execute the body of this loop */
|
/* Note that we might never execute the body of this loop */
|
||||||
@@ -1327,20 +1250,12 @@ start_kdc(krb5_context context,
|
|||||||
kdc_log(context, config, 3, "KDC worker process started: %d",
|
kdc_log(context, config, 3, "KDC worker process started: %d",
|
||||||
pid);
|
pid);
|
||||||
num_kdcs++;
|
num_kdcs++;
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
sd_notifyf(0, "STATUS=Serving requests; %d of %d KDC worker "
|
|
||||||
"process(es) running", num_kdcs, max_kdcs);
|
|
||||||
#endif
|
|
||||||
/* Slow down the creation of KDCs... */
|
/* Slow down the creation of KDCs... */
|
||||||
select_sleep(12500);
|
select_sleep(12500);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
sd_notify(0, "STOPPING=1");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Closing these sockets should cause the kids to die... */
|
/* Closing these sockets should cause the kids to die... */
|
||||||
|
|
||||||
close(islive[0]);
|
close(islive[0]);
|
||||||
@@ -1392,17 +1307,11 @@ start_kdc(krb5_context context,
|
|||||||
kdc_log(context, config, 3, "KDC master process exiting");
|
kdc_log(context, config, 3, "KDC master process exiting");
|
||||||
} else {
|
} else {
|
||||||
loop(context, config, &d, &ndescr, -1);
|
loop(context, config, &d, &ndescr, -1);
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
sd_notify(0, "STOPPING=1");
|
|
||||||
#endif
|
|
||||||
kdc_log(context, config, 3, "KDC exiting");
|
kdc_log(context, config, 3, "KDC exiting");
|
||||||
}
|
}
|
||||||
free(pids);
|
free(pids);
|
||||||
#else
|
#else
|
||||||
loop(context, config, &d, &ndescr, -1);
|
loop(context, config, &d, &ndescr, -1);
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
sd_notify(0, "STOPPING=1");
|
|
||||||
#endif
|
|
||||||
kdc_log(context, config, 3, "KDC exiting");
|
kdc_log(context, config, 3, "KDC exiting");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+4
-6
@@ -460,7 +460,6 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
char *armor_client_principal_name = NULL;
|
char *armor_client_principal_name = NULL;
|
||||||
char *armor_server_principal_name = NULL;
|
char *armor_server_principal_name = NULL;
|
||||||
PA_FX_FAST_REQUEST fxreq;
|
PA_FX_FAST_REQUEST fxreq;
|
||||||
krb5_auth_context free_ac = NULL;
|
|
||||||
krb5_auth_context ac = NULL;
|
krb5_auth_context ac = NULL;
|
||||||
krb5_ticket *ticket = NULL;
|
krb5_ticket *ticket = NULL;
|
||||||
krb5_flags ap_req_options;
|
krb5_flags ap_req_options;
|
||||||
@@ -582,7 +581,7 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_verify_ap_req2(r->context, &free_ac,
|
ret = krb5_verify_ap_req2(r->context, &ac,
|
||||||
&ap_req,
|
&ap_req,
|
||||||
armor_server_principal,
|
armor_server_principal,
|
||||||
&r->armor_key->key,
|
&r->armor_key->key,
|
||||||
@@ -594,8 +593,6 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ac = free_ac;
|
|
||||||
|
|
||||||
ret = krb5_unparse_name(r->context, armor_server_principal,
|
ret = krb5_unparse_name(r->context, armor_server_principal,
|
||||||
&armor_server_principal_name);
|
&armor_server_principal_name);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -624,6 +621,7 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
"<out of memory>");
|
"<out of memory>");
|
||||||
|
|
||||||
if (ac->remote_subkey == NULL) {
|
if (ac->remote_subkey == NULL) {
|
||||||
|
krb5_auth_con_free(r->context, ac);
|
||||||
kdc_log(r->context, r->config, 2,
|
kdc_log(r->context, r->config, 2,
|
||||||
"FAST AP-REQ remote subkey missing");
|
"FAST AP-REQ remote subkey missing");
|
||||||
ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||||
@@ -749,8 +747,8 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
kdc_log(r->context, r->config, 5, "Client selected FAST");
|
kdc_log(r->context, r->config, 5, "Client selected FAST");
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (free_ac)
|
if (ac && ac != tgs_ac)
|
||||||
krb5_auth_con_free(r->context, free_ac);
|
krb5_auth_con_free(r->context, ac);
|
||||||
|
|
||||||
krb5_free_principal(r->context, armor_server_principal);
|
krb5_free_principal(r->context, armor_server_principal);
|
||||||
krb5_xfree(armor_client_principal_name);
|
krb5_xfree(armor_client_principal_name);
|
||||||
|
|||||||
+1
-28
@@ -51,7 +51,7 @@ static const char *kdc_plugin_deps[] = {
|
|||||||
static struct heim_plugin_data kdc_plugin_data = {
|
static struct heim_plugin_data kdc_plugin_data = {
|
||||||
"krb5",
|
"krb5",
|
||||||
"kdc",
|
"kdc",
|
||||||
KRB5_PLUGIN_KDC_VERSION_11,
|
KRB5_PLUGIN_KDC_VERSION_10,
|
||||||
kdc_plugin_deps,
|
kdc_plugin_deps,
|
||||||
kdc_get_instance
|
kdc_get_instance
|
||||||
};
|
};
|
||||||
@@ -239,33 +239,6 @@ _kdc_referral_policy(astgs_request_t r)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code KRB5_LIB_CALL
|
|
||||||
hwauth_policy(krb5_context context, const void *plug, void *plugctx, void *userctx)
|
|
||||||
{
|
|
||||||
const krb5plugin_kdc_ftable *ft = plug;
|
|
||||||
|
|
||||||
if (ft->hwauth_policy == NULL) {
|
|
||||||
return KRB5_PLUGIN_NO_HANDLE;
|
|
||||||
}
|
|
||||||
return ft->hwauth_policy(rk_UNCONST(plug), userctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
krb5_error_code
|
|
||||||
_kdc_hwauth_policy(astgs_request_t r)
|
|
||||||
{
|
|
||||||
krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
|
|
||||||
|
|
||||||
if (have_plugin) {
|
|
||||||
ret = _krb5_plugin_run_f(r->context, &kdc_plugin_data, 0, r, hwauth_policy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != KRB5_PLUGIN_NO_HANDLE) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r->client->flags.require_hwauth ? KRB5KDC_ERR_POLICY : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static krb5_error_code KRB5_LIB_CALL
|
static krb5_error_code KRB5_LIB_CALL
|
||||||
finalize_reply(krb5_context context, const void *plug, void *plugctx, void *userctx)
|
finalize_reply(krb5_context context, const void *plug, void *plugctx, void *userctx)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-12
@@ -95,16 +95,6 @@ typedef krb5_error_code
|
|||||||
typedef krb5_error_code
|
typedef krb5_error_code
|
||||||
(KRB5_CALLCONV *krb5plugin_kdc_referral_policy)(void *, astgs_request_t);
|
(KRB5_CALLCONV *krb5plugin_kdc_referral_policy)(void *, astgs_request_t);
|
||||||
|
|
||||||
/*
|
|
||||||
* A hardware authentication policy plugin can indicate what is to
|
|
||||||
* happen when a client authenticates using a method other than
|
|
||||||
* hardware authentication. It can return zero to allow the
|
|
||||||
* authentication, or an appropriate error code to deny it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef krb5_error_code
|
|
||||||
(KRB5_CALLCONV *krb5plugin_kdc_hwauth_policy)(void *, astgs_request_t);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the AS or TGS reply immediately prior to encoding.
|
* Update the AS or TGS reply immediately prior to encoding.
|
||||||
*/
|
*/
|
||||||
@@ -127,7 +117,7 @@ typedef krb5_error_code
|
|||||||
* Plugins should carefully check API contract notes for changes
|
* Plugins should carefully check API contract notes for changes
|
||||||
* between plugin API versions.
|
* between plugin API versions.
|
||||||
*/
|
*/
|
||||||
#define KRB5_PLUGIN_KDC_VERSION_11 11
|
#define KRB5_PLUGIN_KDC_VERSION_10 10
|
||||||
|
|
||||||
typedef struct krb5plugin_kdc_ftable {
|
typedef struct krb5plugin_kdc_ftable {
|
||||||
HEIM_PLUGIN_FTABLE_COMMON_ELEMENTS(krb5_context);
|
HEIM_PLUGIN_FTABLE_COMMON_ELEMENTS(krb5_context);
|
||||||
@@ -135,7 +125,6 @@ typedef struct krb5plugin_kdc_ftable {
|
|||||||
krb5plugin_kdc_pac_verify pac_verify;
|
krb5plugin_kdc_pac_verify pac_verify;
|
||||||
krb5plugin_kdc_client_access client_access;
|
krb5plugin_kdc_client_access client_access;
|
||||||
krb5plugin_kdc_referral_policy referral_policy;
|
krb5plugin_kdc_referral_policy referral_policy;
|
||||||
krb5plugin_kdc_hwauth_policy hwauth_policy;
|
|
||||||
krb5plugin_kdc_finalize_reply finalize_reply;
|
krb5plugin_kdc_finalize_reply finalize_reply;
|
||||||
krb5plugin_kdc_audit audit;
|
krb5plugin_kdc_audit audit;
|
||||||
} krb5plugin_kdc_ftable;
|
} krb5plugin_kdc_ftable;
|
||||||
|
|||||||
+10
-16
@@ -37,15 +37,16 @@
|
|||||||
#if SIZEOF_TIME_T == 4
|
#if SIZEOF_TIME_T == 4
|
||||||
#define MAX_TIME ((time_t)INT32_MAX)
|
#define MAX_TIME ((time_t)INT32_MAX)
|
||||||
#elif SIZEOF_TIME_T == 8
|
#elif SIZEOF_TIME_T == 8
|
||||||
#define MAX_TIME ((time_t)INT64_MAX)
|
#define MAX_TIME ((time_t)INT32_MAX)
|
||||||
#else
|
#else
|
||||||
#error "Unexpected sizeof(time_t)"
|
#error "Unexpected sizeof(time_t)"
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if SIZEOF_TIME_T == 4
|
#if SIZEOF_TIME_T == 4
|
||||||
#define MAX_TIME ((time_t)UINT32_MAX)
|
#define MAX_TIME ((time_t)INT32_MAX)
|
||||||
#else
|
#else
|
||||||
#define MAX_TIME ((time_t)UINT64_MAX)
|
#define MAX_TIME ((time_t)INT32_MAX)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -535,11 +536,7 @@ pa_pkinit_validate(astgs_request_t r, const PA_DATA *pa)
|
|||||||
|
|
||||||
ret = _kdc_pk_rd_padata(r, pa, &pkp);
|
ret = _kdc_pk_rd_padata(r, pa, &pkp);
|
||||||
if (ret || pkp == NULL) {
|
if (ret || pkp == NULL) {
|
||||||
if (ret == KRB5_KDC_ERR_REVOKED_CERTIFICATE) {
|
|
||||||
ret = KRB5_KDC_ERR_CLIENT_NOT_TRUSTED;
|
|
||||||
} else {
|
|
||||||
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
|
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
|
||||||
}
|
|
||||||
_kdc_r_log(r, 4, "Failed to decode PKINIT PA-DATA -- %s",
|
_kdc_r_log(r, 4, "Failed to decode PKINIT PA-DATA -- %s",
|
||||||
r->cname);
|
r->cname);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -938,9 +935,6 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
free_EncryptedData(&enc_data);
|
free_EncryptedData(&enc_data);
|
||||||
if (ret) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = decode_PA_ENC_TS_ENC(ts_data.data,
|
ret = decode_PA_ENC_TS_ENC(ts_data.data,
|
||||||
ts_data.length,
|
ts_data.length,
|
||||||
&p,
|
&p,
|
||||||
@@ -952,7 +946,7 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
|
|||||||
r->cname);
|
r->cname);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (krb5_time_abs(kdc_time, p.patimestamp) > r->context->max_skew) {
|
if (labs(kdc_time - p.patimestamp) > r->context->max_skew) {
|
||||||
char client_time[100];
|
char client_time[100];
|
||||||
|
|
||||||
krb5_format_time(r->context, p.patimestamp,
|
krb5_format_time(r->context, p.patimestamp,
|
||||||
@@ -962,7 +956,7 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
|
|||||||
_kdc_r_log(r, 4, "Too large time skew, "
|
_kdc_r_log(r, 4, "Too large time skew, "
|
||||||
"client time %s is out by %u > %u seconds -- %s",
|
"client time %s is out by %u > %u seconds -- %s",
|
||||||
client_time,
|
client_time,
|
||||||
(unsigned)krb5_time_abs(kdc_time, p.patimestamp),
|
(unsigned)labs(kdc_time - p.patimestamp),
|
||||||
r->context->max_skew,
|
r->context->max_skew,
|
||||||
r->cname);
|
r->cname);
|
||||||
kdc_audit_setkv_number((kdc_request_t)r, KDC_REQUEST_KV_AUTH_EVENT,
|
kdc_audit_setkv_number((kdc_request_t)r, KDC_REQUEST_KV_AUTH_EVENT,
|
||||||
@@ -2269,13 +2263,13 @@ _kdc_as_rep(astgs_request_t r)
|
|||||||
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
|
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!(pat[n].flags & PA_HARDWARE_AUTH)) {
|
if (r->client->flags.require_hwauth &&
|
||||||
ret = _kdc_hwauth_policy(r);
|
!(pat[n].flags & PA_HARDWARE_AUTH)) {
|
||||||
if (ret) {
|
|
||||||
kdc_log(r->context, config, 4, "Hardware authentication required for %s", r->cname);
|
kdc_log(r->context, config, 4, "Hardware authentication required for %s", r->cname);
|
||||||
|
|
||||||
|
ret = KRB5KDC_ERR_POLICY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
kdc_audit_addkv((kdc_request_t)r, KDC_AUDIT_VIS, "pa", "%s",
|
kdc_audit_addkv((kdc_request_t)r, KDC_AUDIT_VIS, "pa", "%s",
|
||||||
pat[n].name);
|
pat[n].name);
|
||||||
ret = pat[n].validate(r, pa);
|
ret = pat[n].validate(r, pa);
|
||||||
|
|||||||
+17
-10
@@ -399,6 +399,7 @@ mk_error_response(krb5_context context,
|
|||||||
Kx509Response rep;
|
Kx509Response rep;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
char *freeme0 = NULL;
|
char *freeme0 = NULL;
|
||||||
|
char *freeme1 = NULL;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
@@ -416,6 +417,9 @@ mk_error_response(krb5_context context,
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!reqctx->config->enable_kx509)
|
||||||
|
code = KRB5KDC_ERR_POLICY;
|
||||||
|
|
||||||
/* Make sure we only send RFC4120 and friends wire protocol error codes */
|
/* Make sure we only send RFC4120 and friends wire protocol error codes */
|
||||||
if (code) {
|
if (code) {
|
||||||
if (code == KX509_ERR_NONE) {
|
if (code == KX509_ERR_NONE) {
|
||||||
@@ -437,6 +441,12 @@ mk_error_response(krb5_context context,
|
|||||||
msg = freeme0;
|
msg = freeme0;
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
|
if (!reqctx->config->enable_kx509 &&
|
||||||
|
asprintf(&freeme1, "kx509 service is disabled (%s)", msg) > -1 &&
|
||||||
|
freeme1 != NULL) {
|
||||||
|
msg = freeme1;
|
||||||
|
}
|
||||||
|
|
||||||
rep.hash = NULL;
|
rep.hash = NULL;
|
||||||
rep.certificate = NULL;
|
rep.certificate = NULL;
|
||||||
rep.error_code = code;
|
rep.error_code = code;
|
||||||
@@ -458,6 +468,7 @@ mk_error_response(krb5_context context,
|
|||||||
free(rep.e_text);
|
free(rep.e_text);
|
||||||
free(rep.hash);
|
free(rep.hash);
|
||||||
free(freeme0);
|
free(freeme0);
|
||||||
|
free(freeme1);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -889,13 +900,12 @@ _kdc_do_kx509(kx509_req_context r)
|
|||||||
if (r->req.authenticator.length == 0) {
|
if (r->req.authenticator.length == 0) {
|
||||||
/*
|
/*
|
||||||
* Unauthenticated kx509 service availability probe.
|
* Unauthenticated kx509 service availability probe.
|
||||||
|
*
|
||||||
|
* mk_error_response() will check whether the service is enabled and
|
||||||
|
* possibly change the error code and message.
|
||||||
*/
|
*/
|
||||||
is_probe = 1;
|
is_probe = 1;
|
||||||
kdc_audit_addkv((kdc_request_t)r, 0, "probe", "unauthenticated");
|
kdc_audit_addkv((kdc_request_t)r, 0, "probe", "unauthenticated");
|
||||||
if (!r->config->enable_kx509)
|
|
||||||
ret = mk_error_response(r->context, r, 4, KRB5KDC_ERR_POLICY,
|
|
||||||
"kx509 service is disabled");
|
|
||||||
else
|
|
||||||
ret = mk_error_response(r->context, r, 4, 0,
|
ret = mk_error_response(r->context, r, 4, 0,
|
||||||
"kx509 service is available");
|
"kx509 service is available");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -928,12 +938,6 @@ _kdc_do_kx509(kx509_req_context r)
|
|||||||
* Provided we got the session key, errors past this point will be
|
* Provided we got the session key, errors past this point will be
|
||||||
* authenticated.
|
* authenticated.
|
||||||
*/
|
*/
|
||||||
if (ret == 0 && !r->config->enable_kx509) {
|
|
||||||
ret = mk_error_response(r->context, r, 4, KRB5KDC_ERR_POLICY,
|
|
||||||
"kx509 service is disabled");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = krb5_ticket_get_client(r->context, ticket, &cprincipal);
|
ret = krb5_ticket_get_client(r->context, ticket, &cprincipal);
|
||||||
|
|
||||||
@@ -979,6 +983,9 @@ _kdc_do_kx509(kx509_req_context r)
|
|||||||
if (r->req.pk_key.length == 0) {
|
if (r->req.pk_key.length == 0) {
|
||||||
/*
|
/*
|
||||||
* The request is an authenticated kx509 service availability probe.
|
* The request is an authenticated kx509 service availability probe.
|
||||||
|
*
|
||||||
|
* mk_error_response() will check whether the service is enabled and
|
||||||
|
* possibly change the error code and message.
|
||||||
*/
|
*/
|
||||||
is_probe = 1;
|
is_probe = 1;
|
||||||
kdc_audit_addkv((kdc_request_t)r, 0, "probe", "authenticated");
|
kdc_audit_addkv((kdc_request_t)r, 0, "probe", "authenticated");
|
||||||
|
|||||||
+2
-4
@@ -432,7 +432,7 @@ pk_check_pkauthenticator_win2k(krb5_context context,
|
|||||||
krb5_timeofday (context, &now);
|
krb5_timeofday (context, &now);
|
||||||
|
|
||||||
/* XXX cusec */
|
/* XXX cusec */
|
||||||
if (a->ctime == 0 || krb5_time_abs(a->ctime, now) > context->max_skew) {
|
if (a->ctime == 0 || labs(a->ctime - now) > context->max_skew) {
|
||||||
krb5_clear_error_message(context);
|
krb5_clear_error_message(context);
|
||||||
return KRB5KRB_AP_ERR_SKEW;
|
return KRB5KRB_AP_ERR_SKEW;
|
||||||
}
|
}
|
||||||
@@ -451,7 +451,7 @@ pk_check_pkauthenticator(krb5_context context,
|
|||||||
krb5_timeofday (context, &now);
|
krb5_timeofday (context, &now);
|
||||||
|
|
||||||
/* XXX cusec */
|
/* XXX cusec */
|
||||||
if (a->ctime == 0 || krb5_time_abs(a->ctime, now) > context->max_skew) {
|
if (a->ctime == 0 || labs(a->ctime - now) > context->max_skew) {
|
||||||
krb5_clear_error_message(context);
|
krb5_clear_error_message(context);
|
||||||
return KRB5KRB_AP_ERR_SKEW;
|
return KRB5KRB_AP_ERR_SKEW;
|
||||||
}
|
}
|
||||||
@@ -797,8 +797,6 @@ _kdc_pk_rd_padata(astgs_request_t priv,
|
|||||||
hx509_verify_attach_anchors(cp->verify_ctx, trust_anchors);
|
hx509_verify_attach_anchors(cp->verify_ctx, trust_anchors);
|
||||||
hx509_certs_free(&trust_anchors);
|
hx509_certs_free(&trust_anchors);
|
||||||
|
|
||||||
hx509_verify_attach_revoke(cp->verify_ctx, kdc_identity->revokectx);
|
|
||||||
|
|
||||||
if (config->pkinit_allow_proxy_certs)
|
if (config->pkinit_allow_proxy_certs)
|
||||||
hx509_verify_set_proxy_certificate(cp->verify_ctx, 1);
|
hx509_verify_set_proxy_certificate(cp->verify_ctx, 1);
|
||||||
|
|
||||||
|
|||||||
+1
-4
@@ -24,10 +24,7 @@ kpasswdd_LDADD = \
|
|||||||
$(LDADD) \
|
$(LDADD) \
|
||||||
$(LIB_pidfile) \
|
$(LIB_pidfile) \
|
||||||
$(LIB_dlopen) \
|
$(LIB_dlopen) \
|
||||||
$(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB) \
|
$(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB)
|
||||||
$(SYSTEMD_LIBS)
|
|
||||||
|
|
||||||
kpasswdd_CFLAGS = $(SYSTEMD_CFLAGS)
|
|
||||||
|
|
||||||
LDADD = $(top_builddir)/lib/krb5/libkrb5.la \
|
LDADD = $(top_builddir)/lib/krb5/libkrb5.la \
|
||||||
$(top_builddir)/lib/asn1/libasn1.la \
|
$(top_builddir)/lib/asn1/libasn1.la \
|
||||||
|
|||||||
+1
-91
@@ -41,11 +41,6 @@ RCSID("$Id$");
|
|||||||
#include <hdb.h>
|
#include <hdb.h>
|
||||||
#include <kadm5/private.h>
|
#include <kadm5/private.h>
|
||||||
#include <kadm5/kadm5_err.h>
|
#include <kadm5/kadm5_err.h>
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
#include <systemd/sd-daemon.h>
|
|
||||||
/* how often (seconds) to refresh the sd_notify STATUS line while idle */
|
|
||||||
#define STATUS_INTERVAL 30
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static krb5_context context;
|
static krb5_context context;
|
||||||
static krb5_log_facility *log_facility;
|
static krb5_log_facility *log_facility;
|
||||||
@@ -706,58 +701,7 @@ doit(krb5_keytab keytab, int port)
|
|||||||
fd_set real_fdset;
|
fd_set real_fdset;
|
||||||
struct sockaddr_storage __ss;
|
struct sockaddr_storage __ss;
|
||||||
struct sockaddr *sa = (struct sockaddr *)&__ss;
|
struct sockaddr *sa = (struct sockaddr *)&__ss;
|
||||||
int sd_activated = 0;
|
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
{
|
|
||||||
char **names = NULL;
|
|
||||||
int sd_n, j;
|
|
||||||
|
|
||||||
sd_n = sd_listen_fds_with_names(0, &names);
|
|
||||||
if (sd_n < 0)
|
|
||||||
krb5_err(context, 1, -sd_n, "sd_listen_fds_with_names");
|
|
||||||
if (sd_n > 0) {
|
|
||||||
sd_activated = 1;
|
|
||||||
sockets = malloc(sd_n * sizeof(*sockets));
|
|
||||||
if (sockets == NULL)
|
|
||||||
krb5_errx(context, 1, "out of memory");
|
|
||||||
memset(&addrs, 0, sizeof(addrs));
|
|
||||||
addrs.val = malloc(sd_n * sizeof(*addrs.val));
|
|
||||||
if (addrs.val == NULL)
|
|
||||||
krb5_errx(context, 1, "out of memory");
|
|
||||||
n = 0;
|
|
||||||
maxfd = -1;
|
|
||||||
FD_ZERO(&real_fdset);
|
|
||||||
for (j = 0; j < sd_n; j++) {
|
|
||||||
int fd = SD_LISTEN_FDS_START + j;
|
|
||||||
krb5_socklen_t sa_size = sizeof(__ss);
|
|
||||||
|
|
||||||
if (names == NULL || names[j] == NULL ||
|
|
||||||
strncmp(names[j], "kpasswdd", 8) != 0)
|
|
||||||
continue;
|
|
||||||
if (getsockname(fd, sa, &sa_size) < 0) {
|
|
||||||
krb5_warn(context, errno,
|
|
||||||
"getsockname on socket-activated fd %d", fd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (krb5_sockaddr2address(context, sa, &addrs.val[n]) != 0)
|
|
||||||
continue;
|
|
||||||
sockets[n] = fd;
|
|
||||||
maxfd = max(maxfd, fd);
|
|
||||||
if (maxfd >= FD_SETSIZE)
|
|
||||||
krb5_errx(context, 1, "fd too large");
|
|
||||||
FD_SET(fd, &real_fdset);
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
addrs.len = n;
|
|
||||||
}
|
|
||||||
for (j = 0; names != NULL && names[j] != NULL; j++)
|
|
||||||
free(names[j]);
|
|
||||||
free(names);
|
|
||||||
}
|
|
||||||
#endif /* HAVE_SYSTEMD */
|
|
||||||
|
|
||||||
if (!sd_activated) {
|
|
||||||
if (explicit_addresses.len) {
|
if (explicit_addresses.len) {
|
||||||
addrs = explicit_addresses;
|
addrs = explicit_addresses;
|
||||||
} else {
|
} else {
|
||||||
@@ -796,48 +740,22 @@ doit(krb5_keytab keytab, int port)
|
|||||||
krb5_errx(context, 1, "fd too large");
|
krb5_errx(context, 1, "fd too large");
|
||||||
FD_SET(sockets[i], &real_fdset);
|
FD_SET(sockets[i], &real_fdset);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (maxfd == -1)
|
if (maxfd == -1)
|
||||||
krb5_errx(context, 1, "No sockets!");
|
krb5_errx(context, 1, "No sockets!");
|
||||||
|
|
||||||
roken_detach_finish(NULL, daemon_child);
|
roken_detach_finish(NULL, daemon_child);
|
||||||
|
|
||||||
{
|
|
||||||
struct timeval *tmoutp = NULL;
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
unsigned long nrequests = 0;
|
|
||||||
struct timeval tmout;
|
|
||||||
|
|
||||||
tmoutp = &tmout;
|
|
||||||
sd_notify(0, "READY=1");
|
|
||||||
sd_notifyf(0, "STATUS=Serving; %lu password change request(s) processed",
|
|
||||||
nrequests);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (exit_flag == 0) {
|
while (exit_flag == 0) {
|
||||||
krb5_ssize_t retx;
|
krb5_ssize_t retx;
|
||||||
fd_set fdset = real_fdset;
|
fd_set fdset = real_fdset;
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD
|
retx = select(maxfd + 1, &fdset, NULL, NULL, NULL);
|
||||||
tmout.tv_sec = STATUS_INTERVAL;
|
|
||||||
tmout.tv_usec = 0;
|
|
||||||
#endif
|
|
||||||
retx = select(maxfd + 1, &fdset, NULL, NULL, tmoutp);
|
|
||||||
if (retx < 0) {
|
if (retx < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
krb5_err(context, 1, errno, "select");
|
krb5_err(context, 1, errno, "select");
|
||||||
}
|
}
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
if (retx == 0) {
|
|
||||||
/* select timed out: refresh our systemd status line */
|
|
||||||
sd_notifyf(0, "STATUS=Serving; %lu password change request(s) "
|
|
||||||
"processed", nrequests);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
for (i = 0; i < n; ++i)
|
for (i = 0; i < n; ++i)
|
||||||
if (FD_ISSET(sockets[i], &fdset)) {
|
if (FD_ISSET(sockets[i], &fdset)) {
|
||||||
u_char buf[BUFSIZ];
|
u_char buf[BUFSIZ];
|
||||||
@@ -856,16 +774,8 @@ doit(krb5_keytab keytab, int port)
|
|||||||
&addrs.val[i],
|
&addrs.val[i],
|
||||||
sa, addrlen,
|
sa, addrlen,
|
||||||
buf, retx);
|
buf, retx);
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
nrequests++;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD
|
|
||||||
sd_notify(0, "STOPPING=1");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; i < n; ++i)
|
for (i = 0; i < n; ++i)
|
||||||
close(sockets[i]);
|
close(sockets[i]);
|
||||||
|
|||||||
+2
-4
@@ -1104,8 +1104,7 @@ get_new_tickets(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ticket_life != 0) {
|
if (ticket_life != 0) {
|
||||||
if (krb5_time_abs(cred.times.endtime - cred.times.starttime,
|
if (labs(cred.times.endtime - cred.times.starttime - ticket_life) > 30) {
|
||||||
ticket_life) > 30) {
|
|
||||||
char life[64];
|
char life[64];
|
||||||
unparse_time_approx(cred.times.endtime - cred.times.starttime,
|
unparse_time_approx(cred.times.endtime - cred.times.starttime,
|
||||||
life, sizeof(life));
|
life, sizeof(life));
|
||||||
@@ -1113,8 +1112,7 @@ get_new_tickets(krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (renew_life) {
|
if (renew_life) {
|
||||||
if (krb5_time_abs(cred.times.renew_till - cred.times.starttime,
|
if (labs(cred.times.renew_till - cred.times.starttime - renew) > 30) {
|
||||||
renew) > 30) {
|
|
||||||
char life[64];
|
char life[64];
|
||||||
unparse_time_approx(cred.times.renew_till - cred.times.starttime,
|
unparse_time_approx(cred.times.renew_till - cred.times.starttime,
|
||||||
life, sizeof(life));
|
life, sizeof(life));
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
include $(top_srcdir)/Makefile.am.common
|
include $(top_srcdir)/Makefile.am.common
|
||||||
|
|
||||||
|
if LIBEDIT
|
||||||
|
dir_editline = libedit
|
||||||
|
endif
|
||||||
if DCE
|
if DCE
|
||||||
dir_dce = kdfs
|
dir_dce = kdfs
|
||||||
endif
|
endif
|
||||||
@@ -18,6 +21,7 @@ SUBDIRS = \
|
|||||||
vers \
|
vers \
|
||||||
$(dir_com_err) \
|
$(dir_com_err) \
|
||||||
base \
|
base \
|
||||||
|
$(dir_editline) \
|
||||||
sl \
|
sl \
|
||||||
wind \
|
wind \
|
||||||
asn1 \
|
asn1 \
|
||||||
|
|||||||
@@ -97,10 +97,8 @@ der_print_hex_heim_integer (const heim_integer *data, char **p)
|
|||||||
if (data->negative) {
|
if (data->negative) {
|
||||||
len = asprintf(&q, "-%s", *p);
|
len = asprintf(&q, "-%s", *p);
|
||||||
free(*p);
|
free(*p);
|
||||||
if (len < 0) {
|
if (len < 0)
|
||||||
*p = NULL;
|
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
|
||||||
*p = q;
|
*p = q;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -191,7 +191,6 @@ init_generate (const char *filename, const char *base)
|
|||||||
fprintf (headerfile,
|
fprintf (headerfile,
|
||||||
"#include <stddef.h>\n"
|
"#include <stddef.h>\n"
|
||||||
"#include <stdint.h>\n"
|
"#include <stdint.h>\n"
|
||||||
"#include <errno.h>\n"
|
|
||||||
"#include <time.h>\n\n");
|
"#include <time.h>\n\n");
|
||||||
fprintf (headerfile,
|
fprintf (headerfile,
|
||||||
"#ifndef __asn1_common_definitions__\n"
|
"#ifndef __asn1_common_definitions__\n"
|
||||||
@@ -600,8 +599,6 @@ generate_constant (const Symbol *s)
|
|||||||
/* header file */
|
/* header file */
|
||||||
|
|
||||||
gen_upper = strdup(s->gen_name);
|
gen_upper = strdup(s->gen_name);
|
||||||
if (gen_upper == NULL)
|
|
||||||
errx(1, "malloc");
|
|
||||||
len = strlen(gen_upper);
|
len = strlen(gen_upper);
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
gen_upper[i] = toupper((unsigned char)s->gen_name[i]);
|
gen_upper[i] = toupper((unsigned char)s->gen_name[i]);
|
||||||
|
|||||||
@@ -289,11 +289,7 @@ static struct tlist *
|
|||||||
tlist_new(const char *name)
|
tlist_new(const char *name)
|
||||||
{
|
{
|
||||||
struct tlist *tl = calloc(1, sizeof(*tl));
|
struct tlist *tl = calloc(1, sizeof(*tl));
|
||||||
if (tl == NULL)
|
|
||||||
errx(1, "malloc");
|
|
||||||
tl->name = strdup(name);
|
tl->name = strdup(name);
|
||||||
if (tl->name == NULL)
|
|
||||||
errx(1, "malloc");
|
|
||||||
HEIM_TAILQ_INIT(&tl->template);
|
HEIM_TAILQ_INIT(&tl->template);
|
||||||
return tl;
|
return tl;
|
||||||
}
|
}
|
||||||
@@ -425,8 +421,6 @@ add_line(struct templatehead *t, const char *fmt, ...)
|
|||||||
{
|
{
|
||||||
struct template *q = calloc(1, sizeof(*q));
|
struct template *q = calloc(1, sizeof(*q));
|
||||||
va_list ap;
|
va_list ap;
|
||||||
if (q == NULL)
|
|
||||||
errx(1, "malloc");
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
if (vasprintf(&q->line, fmt, ap) < 0 || q->line == NULL)
|
if (vasprintf(&q->line, fmt, ap) < 0 || q->line == NULL)
|
||||||
errx(1, "malloc");
|
errx(1, "malloc");
|
||||||
|
|||||||
+14
-22
@@ -38,26 +38,12 @@
|
|||||||
#include <vis.h>
|
#include <vis.h>
|
||||||
#include <vis-extras.h>
|
#include <vis-extras.h>
|
||||||
#include <heimbase.h>
|
#include <heimbase.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#ifndef ENOTSUP
|
#ifndef ENOTSUP
|
||||||
/* Very old MSVC CRTs don't have ENOTSUP */
|
/* Very old MSVC CRTs don't have ENOTSUP */
|
||||||
#define ENOTSUP EINVAL
|
#define ENOTSUP EINVAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
|
||||||
int32_ptr_equal(int32_t i, const void *ptr)
|
|
||||||
{
|
|
||||||
const intptr_t v = (intptr_t)ptr;
|
|
||||||
|
|
||||||
#if INTPTR_MAX > INT32_MAX || INTPTR_MIN < INT32_MIN
|
|
||||||
if (v > INT32_MAX || v < INT32_MIN)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return i == (int32_t)v;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
|
struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
|
||||||
#define el(name, type) { \
|
#define el(name, type) { \
|
||||||
(asn1_type_encode)der_put_##name, \
|
(asn1_type_encode)der_put_##name, \
|
||||||
@@ -1507,7 +1493,9 @@ _asn1_encode(const struct asn1_template *t, unsigned char *p, size_t len, const
|
|||||||
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
||||||
const int32_t *i = el;
|
const int32_t *i = el;
|
||||||
|
|
||||||
if (int32_ptr_equal(*i, tdefval->ptr))
|
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
||||||
|
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
|
||||||
|
*i == (int32_t)(intptr_t)tdefval->ptr)
|
||||||
break;
|
break;
|
||||||
} else if (tdefval->tt & A1_DV_INTEGER) {
|
} else if (tdefval->tt & A1_DV_INTEGER) {
|
||||||
const struct heim_integer *i = el;
|
const struct heim_integer *i = el;
|
||||||
@@ -1579,7 +1567,9 @@ _asn1_encode(const struct asn1_template *t, unsigned char *p, size_t len, const
|
|||||||
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
||||||
const int32_t *i = data;
|
const int32_t *i = data;
|
||||||
|
|
||||||
if (int32_ptr_equal(*i, tdefval->ptr))
|
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
||||||
|
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
|
||||||
|
*i == (int32_t)(intptr_t)tdefval->ptr)
|
||||||
exclude = 1;
|
exclude = 1;
|
||||||
} else if (tdefval->tt & A1_DV_INTEGER) {
|
} else if (tdefval->tt & A1_DV_INTEGER) {
|
||||||
const struct heim_integer *i = data;
|
const struct heim_integer *i = data;
|
||||||
@@ -2082,7 +2072,9 @@ _asn1_length(const struct asn1_template *t, const void *data)
|
|||||||
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
||||||
const int32_t *i = el;
|
const int32_t *i = el;
|
||||||
|
|
||||||
if (int32_ptr_equal(*i, tdefval->ptr))
|
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
||||||
|
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
|
||||||
|
*i == (int32_t)(intptr_t)tdefval->ptr)
|
||||||
break;
|
break;
|
||||||
} else if (tdefval->tt & A1_DV_INTEGER) {
|
} else if (tdefval->tt & A1_DV_INTEGER) {
|
||||||
const struct heim_integer *i = el;
|
const struct heim_integer *i = el;
|
||||||
@@ -2139,7 +2131,9 @@ _asn1_length(const struct asn1_template *t, const void *data)
|
|||||||
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
||||||
const int32_t *i = data;
|
const int32_t *i = data;
|
||||||
|
|
||||||
if (int32_ptr_equal(*i, tdefval->ptr))
|
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
||||||
|
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
|
||||||
|
*i == (int32_t)(intptr_t)tdefval->ptr)
|
||||||
exclude = 1;
|
exclude = 1;
|
||||||
} else if (tdefval->tt & A1_DV_INTEGER) {
|
} else if (tdefval->tt & A1_DV_INTEGER) {
|
||||||
const struct heim_integer *i = data;
|
const struct heim_integer *i = data;
|
||||||
@@ -2489,10 +2483,8 @@ _asn1_print_open_type(const struct asn1_template *t, /* object set template */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
||||||
size_t offset = t->offset + sizeof(*elementp);
|
unsigned align = 8 - ((t->offset + sizeof(*elementp)) & 0x7);
|
||||||
|
dp = DPOC(data, t->offset + sizeof(*elementp) + align);
|
||||||
offset += (sizeof(void *) - offset % sizeof(void *)) % sizeof(void *);
|
|
||||||
dp = DPOC(data, offset);
|
|
||||||
if (*dp) {
|
if (*dp) {
|
||||||
struct rk_strpool *r2 = NULL;
|
struct rk_strpool *r2 = NULL;
|
||||||
char *s = NULL;
|
char *s = NULL;
|
||||||
|
|||||||
+2
-17
@@ -46,21 +46,6 @@ static const unsigned ndays[2][12] ={
|
|||||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
||||||
|
|
||||||
static time_t
|
|
||||||
_clamp_time_t(uint64_t t)
|
|
||||||
{
|
|
||||||
#if SIZEOF_TIME_T < 8
|
|
||||||
#ifdef TIME_T_UNSIGNED
|
|
||||||
#define MAX_TIME ((UINT64_C(1) << (SIZEOF_TIME_T * 8)) - 1)
|
|
||||||
#else
|
|
||||||
#define MAX_TIME ((UINT64_C(1) << ((SIZEOF_TIME_T * 8) - 1)) - 1)
|
|
||||||
#endif
|
|
||||||
return t < MAX_TIME ? t : MAX_TIME;
|
|
||||||
#else
|
|
||||||
return t;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a simplifed version of timegm(3) that doesn't accept out of
|
* This is a simplifed version of timegm(3) that doesn't accept out of
|
||||||
* bound values that timegm(3) normally accepts but those are not
|
* bound values that timegm(3) normally accepts but those are not
|
||||||
@@ -70,7 +55,7 @@ _clamp_time_t(uint64_t t)
|
|||||||
time_t
|
time_t
|
||||||
_der_timegm (struct tm *tm)
|
_der_timegm (struct tm *tm)
|
||||||
{
|
{
|
||||||
uint64_t res = 0;
|
time_t res = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -104,7 +89,7 @@ _der_timegm (struct tm *tm)
|
|||||||
res += tm->tm_min;
|
res += tm->tm_min;
|
||||||
res *= 60;
|
res *= 60;
|
||||||
res += tm->tm_sec;
|
res += tm->tm_sec;
|
||||||
return _clamp_time_t(res);
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tm *
|
struct tm *
|
||||||
|
|||||||
+3
-23
@@ -86,26 +86,6 @@ static heim_error_code parse_list(struct fileptr *f, unsigned *lineno,
|
|||||||
heim_config_binding **parent,
|
heim_config_binding **parent,
|
||||||
const char **err_message);
|
const char **err_message);
|
||||||
|
|
||||||
static int
|
|
||||||
todash(int c)
|
|
||||||
{
|
|
||||||
if (c == '_')
|
|
||||||
return '-';
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
strcmp_du(const char *s1, const char *s2)
|
|
||||||
{
|
|
||||||
while (todash((unsigned char)*s1) == todash((unsigned char)*s2)) {
|
|
||||||
if (*s1 == '\0')
|
|
||||||
return 0;
|
|
||||||
s1++;
|
|
||||||
s2++;
|
|
||||||
}
|
|
||||||
return todash((unsigned char)*s1) - todash((unsigned char)*s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
heim_config_section *
|
heim_config_section *
|
||||||
heim_config_get_entry(heim_config_section **parent, const char *name, int type)
|
heim_config_get_entry(heim_config_section **parent, const char *name, int type)
|
||||||
{
|
{
|
||||||
@@ -114,7 +94,7 @@ heim_config_get_entry(heim_config_section **parent, const char *name, int type)
|
|||||||
for (q = parent; *q != NULL; q = &(*q)->next)
|
for (q = parent; *q != NULL; q = &(*q)->next)
|
||||||
if (type == heim_config_list &&
|
if (type == heim_config_list &&
|
||||||
(unsigned)type == (*q)->type &&
|
(unsigned)type == (*q)->type &&
|
||||||
strcmp_du(name, (*q)->name) == 0)
|
strcmp(name, (*q)->name) == 0)
|
||||||
return *q;
|
return *q;
|
||||||
*q = calloc(1, sizeof(**q));
|
*q = calloc(1, sizeof(**q));
|
||||||
if (*q == NULL)
|
if (*q == NULL)
|
||||||
@@ -808,7 +788,7 @@ vget_next(heim_context context,
|
|||||||
const char *p = va_arg(args, const char *);
|
const char *p = va_arg(args, const char *);
|
||||||
|
|
||||||
while (b != NULL) {
|
while (b != NULL) {
|
||||||
if (strcmp_du(b->name, name) == 0) {
|
if (strcmp(b->name, name) == 0) {
|
||||||
if (b->type == (unsigned)type && p == NULL) {
|
if (b->type == (unsigned)type && p == NULL) {
|
||||||
*pointer = b;
|
*pointer = b;
|
||||||
return b->u.generic;
|
return b->u.generic;
|
||||||
@@ -846,7 +826,7 @@ heim_config_vget_next(heim_context context,
|
|||||||
/* we were called again, so just look for more entries with the
|
/* we were called again, so just look for more entries with the
|
||||||
same name and type */
|
same name and type */
|
||||||
for (b = (*pointer)->next; b != NULL; b = b->next) {
|
for (b = (*pointer)->next; b != NULL; b = b->next) {
|
||||||
if(strcmp_du(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) {
|
if(strcmp(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) {
|
||||||
*pointer = b;
|
*pointer = b;
|
||||||
return b->u.generic;
|
return b->u.generic;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-28
@@ -355,12 +355,11 @@ open_file(heim_context context, heim_log_facility *fac, int min, int max,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static heim_error_code
|
heim_error_code
|
||||||
addlog_dest(heim_context context, heim_log_facility *f,
|
heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig)
|
||||||
const char *orig, int default_min, int default_max)
|
|
||||||
{
|
{
|
||||||
heim_error_code ret = 0;
|
heim_error_code ret = 0;
|
||||||
int min = default_min, max = default_max, n;
|
int min = 0, max = 3, n;
|
||||||
char c;
|
char c;
|
||||||
const char *p = orig;
|
const char *p = orig;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -394,6 +393,8 @@ addlog_dest(heim_context context, heim_log_facility *f,
|
|||||||
return HEIM_ERR_LOG_PARSE;
|
return HEIM_ERR_LOG_PARSE;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
|
} else {
|
||||||
|
max = 5;
|
||||||
}
|
}
|
||||||
if (strcmp(p, "STDERR") == 0) {
|
if (strcmp(p, "STDERR") == 0) {
|
||||||
ret = open_file(context, f, min, max, NULL, "a", stderr,
|
ret = open_file(context, f, min, max, NULL, "a", stderr,
|
||||||
@@ -444,12 +445,6 @@ addlog_dest(heim_context context, heim_log_facility *f,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
heim_error_code
|
|
||||||
heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig)
|
|
||||||
{
|
|
||||||
return addlog_dest(context, f, orig, 0, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
heim_error_code
|
heim_error_code
|
||||||
heim_openlog(heim_context context,
|
heim_openlog(heim_context context,
|
||||||
const char *program,
|
const char *program,
|
||||||
@@ -653,9 +648,9 @@ heim_add_warn_dest(heim_context context, const char *program,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static heim_error_code
|
heim_error_code
|
||||||
add_debug_dest(heim_context context, const char *program,
|
heim_add_debug_dest(heim_context context, const char *program,
|
||||||
const char *log_spec, int default_min, int default_max)
|
const char *log_spec)
|
||||||
{
|
{
|
||||||
heim_log_facility *fac;
|
heim_log_facility *fac;
|
||||||
heim_error_code ret;
|
heim_error_code ret;
|
||||||
@@ -667,26 +662,12 @@ add_debug_dest(heim_context context, const char *program,
|
|||||||
heim_set_debug_dest(context, fac);
|
heim_set_debug_dest(context, fac);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = addlog_dest(context, fac, log_spec, default_min, default_max);
|
ret = heim_addlog_dest(context, fac, log_spec);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
heim_error_code
|
|
||||||
heim_add_debug_dest(heim_context context, const char *program,
|
|
||||||
const char *log_spec)
|
|
||||||
{
|
|
||||||
return add_debug_dest(context, program, log_spec, 0, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
heim_error_code
|
|
||||||
heim_add_trace_dest(heim_context context, const char *program,
|
|
||||||
const char *log_spec)
|
|
||||||
{
|
|
||||||
return add_debug_dest(context, program, log_spec, 0, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct heim_audit_kv_tuple {
|
struct heim_audit_kv_tuple {
|
||||||
heim_string_t key;
|
heim_string_t key;
|
||||||
heim_object_t value;
|
heim_object_t value;
|
||||||
|
|||||||
@@ -142,83 +142,6 @@ test_rwlock(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
file_contains(const char *filename, const char *needle)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
FILE *f;
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
f = fopen(filename, "r");
|
|
||||||
if (f == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), f) != NULL) {
|
|
||||||
if (strstr(buf, needle) != NULL) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
test_log_dest(void)
|
|
||||||
{
|
|
||||||
const char *normal = "test-log-dest.log";
|
|
||||||
const char *trace = "test-trace-dest.log";
|
|
||||||
const char *explicit = "test-trace-explicit-dest.log";
|
|
||||||
heim_log_facility *fac = NULL;
|
|
||||||
heim_context context;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
unlink(normal);
|
|
||||||
unlink(trace);
|
|
||||||
unlink(explicit);
|
|
||||||
|
|
||||||
context = heim_context_init();
|
|
||||||
heim_assert(context != NULL, "heim_context_init failed");
|
|
||||||
|
|
||||||
ret = heim_initlog(context, "test_base", &fac);
|
|
||||||
heim_assert(ret == 0, "heim_initlog failed");
|
|
||||||
ret = heim_addlog_dest(context, fac, normal);
|
|
||||||
heim_assert(ret == 0, "heim_addlog_dest failed");
|
|
||||||
|
|
||||||
heim_log(context, fac, 10, "normal level 10");
|
|
||||||
heim_log(context, fac, 5, "normal level 5");
|
|
||||||
heim_closelog(context, fac);
|
|
||||||
|
|
||||||
heim_assert(!file_contains(normal, "normal level 10"),
|
|
||||||
"normal log destination traced level 10 by default");
|
|
||||||
heim_assert(file_contains(normal, "normal level 5"),
|
|
||||||
"normal log destination did not log level 5 by default");
|
|
||||||
|
|
||||||
ret = heim_add_trace_dest(context, "test_base", trace);
|
|
||||||
heim_assert(ret == 0, "heim_add_trace_dest failed");
|
|
||||||
ret = heim_add_trace_dest(context, "test_base",
|
|
||||||
"5/FILE:test-trace-explicit-dest.log");
|
|
||||||
heim_assert(ret == 0, "heim_add_trace_dest with explicit level failed");
|
|
||||||
|
|
||||||
heim_debug(context, 10, "trace level 10");
|
|
||||||
heim_debug(context, 5, "trace level 5");
|
|
||||||
|
|
||||||
heim_assert(file_contains(trace, "trace level 10"),
|
|
||||||
"trace log destination did not trace level 10 by default");
|
|
||||||
heim_assert(!file_contains(explicit, "trace level 10"),
|
|
||||||
"explicit trace destination ignored its level filter");
|
|
||||||
heim_assert(file_contains(explicit, "trace level 5"),
|
|
||||||
"explicit trace destination did not log matching level");
|
|
||||||
|
|
||||||
heim_context_free(&context);
|
|
||||||
|
|
||||||
unlink(normal);
|
|
||||||
unlink(trace);
|
|
||||||
unlink(explicit);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
test_dict(void)
|
test_dict(void)
|
||||||
{
|
{
|
||||||
@@ -1442,7 +1365,6 @@ main(int argc, char **argv)
|
|||||||
res |= test_memory();
|
res |= test_memory();
|
||||||
res |= test_mutex();
|
res |= test_mutex();
|
||||||
res |= test_rwlock();
|
res |= test_rwlock();
|
||||||
res |= test_log_dest();
|
|
||||||
res |= test_dict();
|
res |= test_dict();
|
||||||
res |= test_auto_release();
|
res |= test_auto_release();
|
||||||
res |= test_string();
|
res |= test_string();
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ HEIMDAL_BASE_1.0 {
|
|||||||
heim_abort;
|
heim_abort;
|
||||||
heim_abortv;
|
heim_abortv;
|
||||||
heim_add_debug_dest;
|
heim_add_debug_dest;
|
||||||
heim_add_trace_dest;
|
|
||||||
heim_add_et_list;
|
heim_add_et_list;
|
||||||
heim_addlog_dest;
|
heim_addlog_dest;
|
||||||
heim_addlog_func;
|
heim_addlog_func;
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
.Fl r
|
.Fl r
|
||||||
.Op Fl MNln
|
.Op Fl MNln
|
||||||
.Op Fl C Ar ccache
|
.Op Fl C Ar ccache
|
||||||
.Op Fl L Ar localuser
|
|
||||||
.Op Fl S Ar maxsize
|
.Op Fl S Ar maxsize
|
||||||
.Op Fl c count
|
.Op Fl c count
|
||||||
.Op Fl m mech
|
.Op Fl m mech
|
||||||
@@ -36,11 +35,6 @@ write an accepted delegated credential into
|
|||||||
This only makes sense if
|
This only makes sense if
|
||||||
.Fl r
|
.Fl r
|
||||||
is specified.
|
is specified.
|
||||||
.It Fl L Ar localuser
|
|
||||||
try to authorize as
|
|
||||||
.Ar localuser
|
|
||||||
with
|
|
||||||
.Fn gss_authorize_localname .
|
|
||||||
.It Fl D
|
.It Fl D
|
||||||
delegate credentials.
|
delegate credentials.
|
||||||
This only makes sense as a client, that is when
|
This only makes sense as a client, that is when
|
||||||
|
|||||||
+7
-37
@@ -435,13 +435,11 @@ initiate_many(gss_name_t service, int delegate, int negotiate, int memcache,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
accept_one(gss_name_t service, const char *ccname, const char *localuser,
|
accept_one(gss_name_t service, const char *ccname, int negotiate)
|
||||||
int negotiate)
|
|
||||||
{
|
{
|
||||||
gss_cred_id_t cred = NULL;
|
gss_cred_id_t cred = NULL;
|
||||||
gss_cred_id_t deleg_creds = NULL;
|
gss_cred_id_t deleg_creds = NULL;
|
||||||
gss_name_t client = GSS_C_NO_NAME;
|
gss_name_t client;
|
||||||
gss_name_t lname = GSS_C_NO_NAME;
|
|
||||||
gss_OID mech_oid;
|
gss_OID mech_oid;
|
||||||
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
||||||
gss_buffer_desc in = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc in = GSS_C_EMPTY_BUFFER;
|
||||||
@@ -497,23 +495,8 @@ accept_one(gss_name_t service, const char *ccname, const char *localuser,
|
|||||||
printf("Authenticated: %.*s\n", (int)dname.length,
|
printf("Authenticated: %.*s\n", (int)dname.length,
|
||||||
(char *)dname.value);
|
(char *)dname.value);
|
||||||
(void) gss_release_buffer(&min, &dname);
|
(void) gss_release_buffer(&min, &dname);
|
||||||
|
(void) gss_release_name(&min, &client);
|
||||||
if (localuser) {
|
(void) gss_delete_sec_context(&min, &ctx, GSS_C_NO_BUFFER);
|
||||||
gss_buffer_desc lnamebuf;
|
|
||||||
|
|
||||||
lnamebuf.length = strlen(localuser);
|
|
||||||
lnamebuf.value = rk_UNCONST(localuser);
|
|
||||||
|
|
||||||
maj = gss_import_name(&min, &lnamebuf,
|
|
||||||
GSS_C_NT_USER_NAME, &lname);
|
|
||||||
GBAIL("gss_import_name", maj, min);
|
|
||||||
|
|
||||||
maj = gss_authorize_localname(&min, client, lname);
|
|
||||||
GBAIL("gss_authorize_localname", maj, min);
|
|
||||||
|
|
||||||
if (!nflag)
|
|
||||||
printf("Authorized: %s\n", localuser);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ccname) {
|
if (ccname) {
|
||||||
#ifdef HAVE_GSS_STORE_CRED_INTO
|
#ifdef HAVE_GSS_STORE_CRED_INTO
|
||||||
@@ -549,12 +532,6 @@ bail:
|
|||||||
gss_release_cred(&min, &cred);
|
gss_release_cred(&min, &cred);
|
||||||
if (deleg_creds)
|
if (deleg_creds)
|
||||||
gss_release_cred(&min, &deleg_creds);
|
gss_release_cred(&min, &deleg_creds);
|
||||||
if (lname)
|
|
||||||
gss_release_name(&min, &lname);
|
|
||||||
if (client)
|
|
||||||
gss_release_name(&min, &client);
|
|
||||||
if (ctx != GSS_C_NO_CONTEXT)
|
|
||||||
gss_delete_sec_context(&min, &ctx, GSS_C_NO_BUFFER);
|
|
||||||
|
|
||||||
free(in.value);
|
free(in.value);
|
||||||
|
|
||||||
@@ -608,8 +585,8 @@ usage(int ecode)
|
|||||||
{
|
{
|
||||||
FILE *f = ecode == 0 ? stdout : stderr;
|
FILE *f = ecode == 0 ? stdout : stderr;
|
||||||
fprintf(f, "Usage: gss-token [-DNn] [-c count] service@host\n");
|
fprintf(f, "Usage: gss-token [-DNn] [-c count] service@host\n");
|
||||||
fprintf(f, " gss-token -r [-Nln] [-C ccache] [-L localuser] "
|
fprintf(f, " gss-token -r [-Nln] [-C ccache] [-c count] "
|
||||||
"[-c count] [service@host]\n");
|
"[service@host]\n");
|
||||||
exit(ecode);
|
exit(ecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,14 +606,12 @@ main(int argc, char **argv)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
int optidx = 0;
|
int optidx = 0;
|
||||||
char *ccname = NULL;
|
char *ccname = NULL;
|
||||||
char *localuser = NULL;
|
|
||||||
char *mech = NULL;
|
char *mech = NULL;
|
||||||
struct getargs args[] = {
|
struct getargs args[] = {
|
||||||
{ "help", 'h', arg_flag, &hflag, NULL, NULL },
|
{ "help", 'h', arg_flag, &hflag, NULL, NULL },
|
||||||
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
||||||
{ NULL, 'C', arg_string, &ccname, NULL, NULL },
|
{ NULL, 'C', arg_string, &ccname, NULL, NULL },
|
||||||
{ NULL, 'D', arg_flag, &Dflag, NULL, NULL },
|
{ NULL, 'D', arg_flag, &Dflag, NULL, NULL },
|
||||||
{ NULL, 'L', arg_string, &localuser, NULL, NULL },
|
|
||||||
{ NULL, 'M', arg_flag, &Mflag, NULL, NULL },
|
{ NULL, 'M', arg_flag, &Mflag, NULL, NULL },
|
||||||
{ NULL, 'N', arg_flag, &Nflag, NULL, NULL },
|
{ NULL, 'N', arg_flag, &Nflag, NULL, NULL },
|
||||||
{ NULL, 'S', arg_integer, &Sflag, NULL, NULL },
|
{ NULL, 'S', arg_integer, &Sflag, NULL, NULL },
|
||||||
@@ -687,11 +662,6 @@ main(int argc, char **argv)
|
|||||||
"make sense without -r.\n");
|
"make sense without -r.\n");
|
||||||
usage(1);
|
usage(1);
|
||||||
}
|
}
|
||||||
if (localuser) {
|
|
||||||
fprintf(stderr, "Specifying a local user doesn't make "
|
|
||||||
"sense without -r.\n");
|
|
||||||
usage(1);
|
|
||||||
}
|
|
||||||
ret = initiate_many(service, Dflag, Nflag, Mflag, count);
|
ret = initiate_many(service, Dflag, Nflag, Mflag, count);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -703,7 +673,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = accept_one(service, ccname, localuser, Nflag);
|
ret = accept_one(service, ccname, Nflag);
|
||||||
} while (lflag && !ret && !feof(stdin));
|
} while (lflag && !ret && !feof(stdin));
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|||||||
@@ -926,7 +926,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred_from
|
|||||||
NULL, time_rec, NULL, actual_mechs);
|
NULL, time_rec, NULL, actual_mechs);
|
||||||
if (ret != GSS_S_COMPLETE) {
|
if (ret != GSS_S_COMPLETE) {
|
||||||
if (handle->mechanisms != NULL)
|
if (handle->mechanisms != NULL)
|
||||||
gss_release_oid_set(minor_status, &handle->mechanisms);
|
gss_release_oid_set(NULL, &handle->mechanisms);
|
||||||
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
|
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
|
||||||
krb5_free_principal(context, handle->principal);
|
krb5_free_principal(context, handle->principal);
|
||||||
free(handle);
|
free(handle);
|
||||||
|
|||||||
@@ -238,7 +238,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred_from (
|
|||||||
|
|
||||||
failure:
|
failure:
|
||||||
if (handle) {
|
if (handle) {
|
||||||
OM_uint32 tmp_status;
|
|
||||||
if (handle->principal)
|
if (handle->principal)
|
||||||
krb5_free_principal(context, handle->principal);
|
krb5_free_principal(context, handle->principal);
|
||||||
if (handle->keytab)
|
if (handle->keytab)
|
||||||
@@ -246,7 +245,7 @@ failure:
|
|||||||
if (handle->ccache)
|
if (handle->ccache)
|
||||||
krb5_cc_destroy(context, handle->ccache);
|
krb5_cc_destroy(context, handle->ccache);
|
||||||
if (handle->mechanisms)
|
if (handle->mechanisms)
|
||||||
gss_release_oid_set(&tmp_status, &handle->mechanisms);
|
gss_release_oid_set(NULL, &handle->mechanisms);
|
||||||
free(handle);
|
free(handle);
|
||||||
}
|
}
|
||||||
if (cred && output_cred_handle)
|
if (cred && output_cred_handle)
|
||||||
|
|||||||
+15
-15
@@ -308,7 +308,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, p, p, 8) != 8) {
|
EVP_Cipher(rc4_key, p, p, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -392,7 +392,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, (void *)k6_data, NULL, 0) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, (void *)k6_data, NULL, 0) != 1 ||
|
||||||
EVP_Cipher(rc4_key, SND_SEQ, p, 8) != 8) {
|
EVP_Cipher(rc4_key, SND_SEQ, p, 8) != 1) {
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
@@ -553,7 +553,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen) != 8 + datalen) {
|
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -581,7 +581,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8) != 8) {
|
EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -690,7 +690,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8) != 8) {
|
EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -747,8 +747,8 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 8 ||
|
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 1 ||
|
||||||
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen) != datalen) {
|
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1149,7 +1149,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
/* Confounder */
|
/* Confounder */
|
||||||
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8) != 8) {
|
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1166,7 +1166,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
||||||
iov[i].buffer.value, iov[i].buffer.length) != iov[i].buffer.length) {
|
iov[i].buffer.value, iov[i].buffer.length) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1177,7 +1177,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
/* Padding */
|
/* Padding */
|
||||||
if (padding &&
|
if (padding &&
|
||||||
EVP_Cipher(rc4_key, padding->buffer.value,
|
EVP_Cipher(rc4_key, padding->buffer.value,
|
||||||
padding->buffer.value, padding->buffer.length) != padding->buffer.length) {
|
padding->buffer.value, padding->buffer.length) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1206,7 +1206,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, p0 + 8, p0 + 8, 8) != 8 /* SND_SEQ */) {
|
EVP_Cipher(rc4_key, p0 + 8, p0 + 8, 8) != 1 /* SND_SEQ */) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1357,7 +1357,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, snd_seq, p0 + 8, 8) != 8 /* SND_SEQ */) {
|
EVP_Cipher(rc4_key, snd_seq, p0 + 8, 8) != 1 /* SND_SEQ */) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1410,7 +1410,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
/* Confounder */
|
/* Confounder */
|
||||||
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 8) {
|
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1427,7 +1427,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
||||||
iov[i].buffer.value, iov[i].buffer.length) != iov[i].buffer.length) {
|
iov[i].buffer.value, iov[i].buffer.length) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1438,7 +1438,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
/* Padding */
|
/* Padding */
|
||||||
if (padding &&
|
if (padding &&
|
||||||
EVP_Cipher(rc4_key, padding->buffer.value,
|
EVP_Cipher(rc4_key, padding->buffer.value,
|
||||||
padding->buffer.value, padding->buffer.length) != padding->buffer.length) {
|
padding->buffer.value, padding->buffer.length) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
|
|||||||
@@ -100,12 +100,11 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_context (
|
|||||||
return GSS_S_COMPLETE;
|
return GSS_S_COMPLETE;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
{ OM_uint32 tmp_status;
|
|
||||||
if (src_name)
|
if (src_name)
|
||||||
_gsskrb5_release_name(&tmp_status, src_name);
|
_gsskrb5_release_name(NULL, src_name);
|
||||||
if (targ_name)
|
if (targ_name)
|
||||||
_gsskrb5_release_name(&tmp_status, targ_name);
|
_gsskrb5_release_name(NULL, targ_name);
|
||||||
}
|
|
||||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_mechs_for_name (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
OM_uint32 ret;
|
OM_uint32 ret;
|
||||||
OM_uint32 tmp_status;
|
|
||||||
|
|
||||||
ret = gss_create_empty_oid_set(minor_status, mech_types);
|
ret = gss_create_empty_oid_set(minor_status, mech_types);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -50,7 +49,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_mechs_for_name (
|
|||||||
GSS_KRB5_MECHANISM,
|
GSS_KRB5_MECHANISM,
|
||||||
mech_types);
|
mech_types);
|
||||||
if (ret)
|
if (ret)
|
||||||
gss_release_oid_set(&tmp_status, mech_types);
|
gss_release_oid_set(NULL, mech_types);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_names_for_mech (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
OM_uint32 ret;
|
OM_uint32 ret;
|
||||||
OM_uint32 tmp_status;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
*minor_status = 0;
|
*minor_status = 0;
|
||||||
@@ -72,7 +71,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_names_for_mech (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret != GSS_S_COMPLETE)
|
if (ret != GSS_S_COMPLETE)
|
||||||
gss_release_oid_set(&tmp_status, name_types);
|
gss_release_oid_set(NULL, name_types);
|
||||||
|
|
||||||
return GSS_S_COMPLETE;
|
return GSS_S_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,25 +83,8 @@ set_proc(OM_uint32 *minor, gss_buffer_set_t env)
|
|||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < env->count; i++) {
|
for (i = 0; i < env->count; i++)
|
||||||
char *var = (char *)env->elements[i].value;
|
putenv(env->elements[i].value);
|
||||||
char *eq = strchr(var, '=');
|
|
||||||
char *val;
|
|
||||||
int e;
|
|
||||||
|
|
||||||
if (eq == NULL) {
|
|
||||||
*minor = EINVAL;
|
|
||||||
return GSS_S_FAILURE;
|
|
||||||
}
|
|
||||||
val = eq + 1;
|
|
||||||
*eq = '\0';
|
|
||||||
e = setenv(var, val, 1);
|
|
||||||
*eq = '=';
|
|
||||||
if (e != 0) {
|
|
||||||
*minor = errno ? errno : EINVAL;
|
|
||||||
return GSS_S_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return GSS_S_COMPLETE;
|
return GSS_S_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,14 +265,12 @@ gss_accept_sec_context(OM_uint32 *minor_status,
|
|||||||
*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
|
*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
|
||||||
_mg_buffer_zero(output_token);
|
_mg_buffer_zero(output_token);
|
||||||
|
|
||||||
_gss_mg_log(10, "gss-asc: enter ctx=%p", ctx);
|
|
||||||
if (!*context_handle) {
|
if (!*context_handle) {
|
||||||
ctx = calloc(1, sizeof(*ctx));
|
ctx = calloc(1, sizeof(*ctx));
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return (GSS_S_DEFECTIVE_TOKEN);
|
return (GSS_S_DEFECTIVE_TOKEN);
|
||||||
}
|
}
|
||||||
_gss_mg_log(10, "gss-asc: allocated ctx=%p", ctx);
|
|
||||||
*context_handle = (gss_ctx_id_t)ctx;
|
*context_handle = (gss_ctx_id_t)ctx;
|
||||||
ctx->gc_initial = 1;
|
ctx->gc_initial = 1;
|
||||||
}
|
}
|
||||||
@@ -320,9 +318,6 @@ gss_accept_sec_context(OM_uint32 *minor_status,
|
|||||||
&mech_ret_flags,
|
&mech_ret_flags,
|
||||||
time_rec,
|
time_rec,
|
||||||
&delegated_mc);
|
&delegated_mc);
|
||||||
_gss_mg_log(10, "gss-asc: ctx=%p tried \"%s\", "
|
|
||||||
"returned %u", ctx, m->gm_name,
|
|
||||||
major_status);
|
|
||||||
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
|
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
|
||||||
/*
|
/*
|
||||||
* Try to retain and output one error token for
|
* Try to retain and output one error token for
|
||||||
@@ -365,9 +360,6 @@ gss_accept_sec_context(OM_uint32 *minor_status,
|
|||||||
&mech_ret_flags,
|
&mech_ret_flags,
|
||||||
time_rec,
|
time_rec,
|
||||||
&delegated_mc);
|
&delegated_mc);
|
||||||
_gss_mg_log(10, "gss-asc: ctx=%p tried \"%s\", "
|
|
||||||
"returned %u", ctx, m->gm_name,
|
|
||||||
major_status);
|
|
||||||
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
|
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
|
||||||
if (output_token->length &&
|
if (output_token->length &&
|
||||||
defective_token_error.length == 0) {
|
defective_token_error.length == 0) {
|
||||||
@@ -518,8 +510,7 @@ got_one:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_gss_mg_log(10, "gss-asc: ctx=%p return %d/%d", ctx,
|
_gss_mg_log(10, "gss-asc: return %d/%d", (int)major_status, (int)*minor_status);
|
||||||
(int)major_status, (int)*minor_status);
|
|
||||||
|
|
||||||
if (ret_flags)
|
if (ret_flags)
|
||||||
*ret_flags = mech_ret_flags;
|
*ret_flags = mech_ret_flags;
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ gss_display_name(OM_uint32 *minor_status,
|
|||||||
struct _gss_name *name = rk_UNCONST(input_name);
|
struct _gss_name *name = rk_UNCONST(input_name);
|
||||||
struct _gss_mechanism_name *mn;
|
struct _gss_mechanism_name *mn;
|
||||||
|
|
||||||
_gss_mg_log(10, "gdn: enter gss_display_name: %p", input_name);
|
|
||||||
_mg_buffer_zero(output_name_buffer);
|
_mg_buffer_zero(output_name_buffer);
|
||||||
if (output_name_type)
|
if (output_name_type)
|
||||||
*output_name_type = GSS_C_NO_OID;
|
*output_name_type = GSS_C_NO_OID;
|
||||||
@@ -69,8 +68,6 @@ gss_display_name(OM_uint32 *minor_status,
|
|||||||
return (GSS_S_COMPLETE);
|
return (GSS_S_COMPLETE);
|
||||||
} else {
|
} else {
|
||||||
HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) {
|
HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) {
|
||||||
_gss_mg_log(10, "gdn: trying mech \"%s\"",
|
|
||||||
mn->gmn_mech->gm_name);
|
|
||||||
major_status = mn->gmn_mech->gm_display_name(
|
major_status = mn->gmn_mech->gm_display_name(
|
||||||
minor_status, mn->gmn_name,
|
minor_status, mn->gmn_name,
|
||||||
output_name_buffer,
|
output_name_buffer,
|
||||||
|
|||||||
@@ -28,8 +28,6 @@
|
|||||||
|
|
||||||
#include "mech_locl.h"
|
#include "mech_locl.h"
|
||||||
|
|
||||||
#include <vis.h>
|
|
||||||
|
|
||||||
static OM_uint32
|
static OM_uint32
|
||||||
_gss_import_export_name(OM_uint32 *minor_status,
|
_gss_import_export_name(OM_uint32 *minor_status,
|
||||||
const gss_buffer_t input_name_buffer,
|
const gss_buffer_t input_name_buffer,
|
||||||
@@ -46,8 +44,6 @@ _gss_import_export_name(OM_uint32 *minor_status,
|
|||||||
gss_name_t new_canonical_name;
|
gss_name_t new_canonical_name;
|
||||||
int composite = 0;
|
int composite = 0;
|
||||||
|
|
||||||
_gss_mg_log(10, "gin: importing exported name");
|
|
||||||
|
|
||||||
*minor_status = 0;
|
*minor_status = 0;
|
||||||
*output_name = 0;
|
*output_name = 0;
|
||||||
|
|
||||||
@@ -173,32 +169,6 @@ _gss_import_export_name(OM_uint32 *minor_status,
|
|||||||
return (GSS_S_COMPLETE);
|
return (GSS_S_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
log_import_name(gss_buffer_t input_name_buffer)
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
if (!_gss_mg_log_level(10))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (input_name_buffer->length > (SIZE_MAX - 1) / 4) {
|
|
||||||
_gss_mg_log(10, "gin: importing name (%zu bytes)",
|
|
||||||
input_name_buffer->length);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = input_name_buffer->length * 4 + 1;
|
|
||||||
name = malloc(len);
|
|
||||||
if (name == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
strsvisx(name, input_name_buffer->value, input_name_buffer->length,
|
|
||||||
VIS_CSTYLE | VIS_TAB | VIS_NL, "\"");
|
|
||||||
_gss_mg_log(10, "gin: importing name \"%s\"", name);
|
|
||||||
free(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a GGS-API name from contiguous string to internal form.
|
* Convert a GGS-API name from contiguous string to internal form.
|
||||||
*
|
*
|
||||||
@@ -260,7 +230,6 @@ gss_import_name(OM_uint32 *minor_status,
|
|||||||
name_type, output_name);
|
name_type, output_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
log_import_name(input_name_buffer);
|
|
||||||
|
|
||||||
*minor_status = 0;
|
*minor_status = 0;
|
||||||
name = _gss_create_name(NULL, NULL);
|
name = _gss_create_name(NULL, NULL);
|
||||||
@@ -293,9 +262,6 @@ gss_import_name(OM_uint32 *minor_status,
|
|||||||
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
||||||
int present = 0;
|
int present = 0;
|
||||||
|
|
||||||
_gss_mg_log(10, "gin: attempting mech \"%s\"",
|
|
||||||
m->gm_mech.gm_name);
|
|
||||||
|
|
||||||
if ((m->gm_mech.gm_flags & GM_USE_MG_NAME))
|
if ((m->gm_mech.gm_flags & GM_USE_MG_NAME))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -167,8 +167,7 @@ do { \
|
|||||||
m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \
|
m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \
|
||||||
if (!m->gm_mech.gm_ ## name || \
|
if (!m->gm_mech.gm_ ## name || \
|
||||||
m->gm_mech.gm_ ##name == gss_ ## name) { \
|
m->gm_mech.gm_ ##name == gss_ ## name) { \
|
||||||
_gss_mg_log(1, "can't find symbol gss_" #name \
|
_gss_mg_log(1, "can't find symbol gss_" #name "\n"); \
|
||||||
" in %s", lib); \
|
|
||||||
goto bad; \
|
goto bad; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -335,11 +334,9 @@ _gss_load_mech(void)
|
|||||||
/*
|
/*
|
||||||
* Check for duplicates, already loaded mechs.
|
* Check for duplicates, already loaded mechs.
|
||||||
*/
|
*/
|
||||||
_gss_mg_log(10, "loading \"%s\"", name);
|
|
||||||
found = 0;
|
found = 0;
|
||||||
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
||||||
if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech_oid)) {
|
if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech_oid)) {
|
||||||
_gss_mg_log(10, "duplicate mech, not loading");
|
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -349,7 +346,7 @@ _gss_load_mech(void)
|
|||||||
|
|
||||||
so = dlopen(lib, RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP);
|
so = dlopen(lib, RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP);
|
||||||
if (so == NULL) {
|
if (so == NULL) {
|
||||||
_gss_mg_log(1, "dlopen: %s", dlerror());
|
_gss_mg_log(1, "dlopen: %s\n", dlerror());
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,8 +99,6 @@ static int help_flag = 0;
|
|||||||
static int env_flag = 0;
|
static int env_flag = 0;
|
||||||
static int def_flag = 0;
|
static int def_flag = 0;
|
||||||
static int overwrite_flag = 0;
|
static int overwrite_flag = 0;
|
||||||
static int store_cred_flag = 0;
|
|
||||||
static char *password = NULL;
|
|
||||||
|
|
||||||
static struct getargs args[] = {
|
static struct getargs args[] = {
|
||||||
{"version", 0, arg_flag, &version_flag, "print version", NULL },
|
{"version", 0, arg_flag, &version_flag, "print version", NULL },
|
||||||
@@ -111,133 +109,16 @@ static struct getargs args[] = {
|
|||||||
"switch credential store default principal", NULL },
|
"switch credential store default principal", NULL },
|
||||||
{"overwrite", 0, arg_flag, &overwrite_flag,
|
{"overwrite", 0, arg_flag, &overwrite_flag,
|
||||||
"overwrite matching credential", NULL },
|
"overwrite matching credential", NULL },
|
||||||
{"store-cred", 0, arg_flag, &store_cred_flag,
|
|
||||||
"use gss_store_cred instead of gss_store_cred_into2", NULL },
|
|
||||||
{"password", 0, arg_string, &password,
|
|
||||||
"acquire source credential with this password", "password" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(int ret)
|
usage(int ret)
|
||||||
{
|
{
|
||||||
arg_printusage(args, sizeof(args)/sizeof(*args),
|
arg_printusage(args, sizeof(args)/sizeof(*args),
|
||||||
NULL, "from_ccache to_ccache | source_name target_name");
|
NULL, "from_ccache to_ccache");
|
||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
add_krb5_mech(gss_OID_set *mechs)
|
|
||||||
{
|
|
||||||
OM_uint32 major, minor;
|
|
||||||
|
|
||||||
major = gss_create_empty_oid_set(&minor, mechs);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_C_NO_OID,
|
|
||||||
"failed to create OID set");
|
|
||||||
|
|
||||||
major = gss_add_oid_set_member(&minor, GSS_KRB5_MECHANISM, mechs);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_C_NO_OID,
|
|
||||||
"failed to add krb5 mechanism to OID set");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
acquire_from_password(const char *source_name,
|
|
||||||
const char *source_password,
|
|
||||||
gss_cred_id_t *cred)
|
|
||||||
{
|
|
||||||
OM_uint32 major, minor;
|
|
||||||
gss_buffer_desc namebuf, pwbuf;
|
|
||||||
gss_name_t name = GSS_C_NO_NAME;
|
|
||||||
gss_OID_set mechs = GSS_C_NO_OID_SET;
|
|
||||||
|
|
||||||
namebuf.value = rk_UNCONST(source_name);
|
|
||||||
namebuf.length = strlen(source_name);
|
|
||||||
major = gss_import_name(&minor, &namebuf, GSS_C_NT_USER_NAME, &name);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_C_NO_OID,
|
|
||||||
"failed to import source name %s", source_name);
|
|
||||||
|
|
||||||
pwbuf.value = rk_UNCONST(source_password);
|
|
||||||
pwbuf.length = strlen(source_password);
|
|
||||||
add_krb5_mech(&mechs);
|
|
||||||
major = gss_acquire_cred_with_password(&minor, name, &pwbuf,
|
|
||||||
GSS_C_INDEFINITE, mechs,
|
|
||||||
GSS_C_INITIATE, cred, NULL, NULL);
|
|
||||||
(void) gss_release_oid_set(&minor, &mechs);
|
|
||||||
(void) gss_release_name(&minor, &name);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
|
||||||
"failed to acquire creds with password for %s", source_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_init_sec_context(gss_cred_id_t cred, const char *target)
|
|
||||||
{
|
|
||||||
OM_uint32 major, minor;
|
|
||||||
gss_buffer_desc namebuf;
|
|
||||||
gss_buffer_desc output_token = { 0, NULL };
|
|
||||||
gss_name_t target_name = GSS_C_NO_NAME;
|
|
||||||
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
|
||||||
|
|
||||||
namebuf.value = rk_UNCONST(target);
|
|
||||||
namebuf.length = strlen(target);
|
|
||||||
major = gss_import_name(&minor, &namebuf, GSS_C_NT_HOSTBASED_SERVICE,
|
|
||||||
&target_name);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_C_NO_OID,
|
|
||||||
"failed to import target name %s", target);
|
|
||||||
|
|
||||||
major = gss_init_sec_context(&minor, cred, &ctx, target_name,
|
|
||||||
GSS_KRB5_MECHANISM, 0, GSS_C_INDEFINITE,
|
|
||||||
GSS_C_NO_CHANNEL_BINDINGS,
|
|
||||||
GSS_C_NO_BUFFER, NULL, &output_token,
|
|
||||||
NULL, NULL);
|
|
||||||
(void) gss_release_buffer(&minor, &output_token);
|
|
||||||
(void) gss_delete_sec_context(&minor, &ctx, GSS_C_NO_BUFFER);
|
|
||||||
(void) gss_release_name(&minor, &target_name);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
|
||||||
"failed to use source cred for %s after storing", target);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
acquire_from_ccache(const char *ccache, gss_cred_id_t *cred)
|
|
||||||
{
|
|
||||||
OM_uint32 major, minor;
|
|
||||||
gss_key_value_element_desc element;
|
|
||||||
gss_key_value_set_desc store;
|
|
||||||
|
|
||||||
element.key = "ccache";
|
|
||||||
element.value = ccache;
|
|
||||||
store.count = 1;
|
|
||||||
store.elements = &element;
|
|
||||||
|
|
||||||
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
|
|
||||||
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
|
|
||||||
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
|
|
||||||
&store, cred, NULL, NULL, NULL);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
|
||||||
"failed to acquire stored creds from %s", ccache);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_default_ccache(gss_cred_id_t from_cred, const char *target)
|
|
||||||
{
|
|
||||||
OM_uint32 minor;
|
|
||||||
const char *ccache = getenv("KRB5CCNAME");
|
|
||||||
gss_cred_id_t to_cred = GSS_C_NO_CREDENTIAL;
|
|
||||||
|
|
||||||
if (ccache == NULL)
|
|
||||||
errx(1, "KRB5CCNAME not set");
|
|
||||||
|
|
||||||
acquire_from_ccache(ccache, &to_cred);
|
|
||||||
check_init_sec_context(from_cred, target);
|
|
||||||
check_init_sec_context(to_cred, target);
|
|
||||||
(void) gss_release_cred(&minor, &to_cred);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -276,16 +157,16 @@ main(int argc, char **argv)
|
|||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
errx(1, "too many arguments");
|
errx(1, "too many arguments");
|
||||||
|
|
||||||
if (password) {
|
|
||||||
if (!store_cred_flag)
|
|
||||||
errx(1, "--password requires --store-cred");
|
|
||||||
acquire_from_password(argv[0], password, &from_cred);
|
|
||||||
} else {
|
|
||||||
from_elements.key = "ccache";
|
from_elements.key = "ccache";
|
||||||
from_elements.value = argv[0];
|
from_elements.value = argv[0];
|
||||||
from.count = 1;
|
from.count = 1;
|
||||||
from.elements = &from_elements;
|
from.elements = &from_elements;
|
||||||
|
|
||||||
|
to_elements.key = "ccache";
|
||||||
|
to_elements.value = argv[1];
|
||||||
|
to.count = 1;
|
||||||
|
to.elements = &to_elements;
|
||||||
|
|
||||||
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
|
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
|
||||||
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
|
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
|
||||||
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
|
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
|
||||||
@@ -293,25 +174,13 @@ main(int argc, char **argv)
|
|||||||
if (major != GSS_S_COMPLETE)
|
if (major != GSS_S_COMPLETE)
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
||||||
"failed to acquire creds from %s", argv[0]);
|
"failed to acquire creds from %s", argv[0]);
|
||||||
}
|
|
||||||
|
|
||||||
if (store_cred_flag) {
|
|
||||||
major = gss_store_cred(&minor, from_cred, GSS_C_INITIATE,
|
|
||||||
GSS_KRB5_MECHANISM, overwrite_flag, def_flag,
|
|
||||||
NULL, NULL);
|
|
||||||
} else {
|
|
||||||
to_elements.key = "ccache";
|
|
||||||
to_elements.value = argv[1];
|
|
||||||
to.count = 1;
|
|
||||||
to.elements = &to_elements;
|
|
||||||
|
|
||||||
major = gss_store_cred_into2(&minor, from_cred, GSS_C_INITIATE,
|
major = gss_store_cred_into2(&minor, from_cred, GSS_C_INITIATE,
|
||||||
GSS_KRB5_MECHANISM, store_flags, &to, NULL,
|
GSS_KRB5_MECHANISM, store_flags, &to, NULL,
|
||||||
NULL, env_flag ? &env : NULL);
|
NULL, env_flag ? &env : NULL);
|
||||||
}
|
|
||||||
if (major != GSS_S_COMPLETE)
|
if (major != GSS_S_COMPLETE)
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
||||||
"failed to store creds");
|
"failed to store creds into %s", argv[1]);
|
||||||
|
|
||||||
if (env_flag) {
|
if (env_flag) {
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -335,22 +204,6 @@ main(int argc, char **argv)
|
|||||||
"gss_store_cred_into2()");
|
"gss_store_cred_into2()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password)
|
|
||||||
check_default_ccache(from_cred, argv[1]);
|
|
||||||
|
|
||||||
if (store_cred_flag) {
|
|
||||||
(void) gss_release_cred(&minor, &from_cred);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
|
|
||||||
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
|
|
||||||
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
|
|
||||||
&to, &to_cred, NULL, NULL, NULL);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
|
||||||
"failed to acquire stored creds from %s", argv[1]);
|
|
||||||
|
|
||||||
(void) gss_release_cred(&minor, &from_cred);
|
(void) gss_release_cred(&minor, &from_cred);
|
||||||
(void) gss_release_cred(&minor, &to_cred);
|
(void) gss_release_cred(&minor, &to_cred);
|
||||||
|
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ loop(gss_OID mechoid,
|
|||||||
if (*deleg_cred != GSS_C_NO_CREDENTIAL)
|
if (*deleg_cred != GSS_C_NO_CREDENTIAL)
|
||||||
errx(1, "got delegated cred but didn't expect one");
|
errx(1, "got delegated cred but didn't expect one");
|
||||||
} else if (*deleg_cred == GSS_C_NO_CREDENTIAL)
|
} else if (*deleg_cred == GSS_C_NO_CREDENTIAL)
|
||||||
errx(1, "asked for delegated cred but did get one");
|
errx(1, "asked for delegarated cred but did get one");
|
||||||
} else if (*deleg_cred != GSS_C_NO_CREDENTIAL)
|
} else if (*deleg_cred != GSS_C_NO_CREDENTIAL)
|
||||||
errx(1, "got deleg_cred cred but didn't ask");
|
errx(1, "got deleg_cred cred but didn't ask");
|
||||||
|
|
||||||
|
|||||||
@@ -149,10 +149,55 @@ hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal,
|
|||||||
* enctypes should work.
|
* enctypes should work.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Debug: record the requested principal and keytab context */
|
||||||
|
{
|
||||||
|
char *princ_name = NULL;
|
||||||
|
if (krb5_unparse_name(context, principal, &princ_name) == 0) {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: looking up principal=%s in keytab=%s kvno=%u flags=0x%x",
|
||||||
|
princ_name ? princ_name : "<unparsed>",
|
||||||
|
k->path ? k->path : "<unknown>",
|
||||||
|
(unsigned)kvno,
|
||||||
|
(unsigned)flags);
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: looking up <unparsed principal> in keytab=%s kvno=%u flags=0x%x",
|
||||||
|
k->path ? k->path : "<unknown>",
|
||||||
|
(unsigned)kvno,
|
||||||
|
(unsigned)flags);
|
||||||
|
}
|
||||||
|
free(princ_name);
|
||||||
|
}
|
||||||
|
|
||||||
ret = krb5_kt_get_entry(context, k->keytab, principal, kvno, 0, &ktentry);
|
ret = krb5_kt_get_entry(context, k->keytab, principal, kvno, 0, &ktentry);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
char *princ_name2 = NULL;
|
||||||
|
if (krb5_unparse_name(context, principal, &princ_name2) == 0) {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: krb5_kt_get_entry returned %d for principal=%s keytab=%s",
|
||||||
|
ret, princ_name2 ? princ_name2 : "<unparsed>", k->path ? k->path : "<unknown>");
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: krb5_kt_get_entry returned %d for <unparsed principal> keytab=%s",
|
||||||
|
ret, k->path ? k->path : "<unknown>");
|
||||||
|
}
|
||||||
|
free(princ_name2);
|
||||||
ret = HDB_ERR_NOENTRY;
|
ret = HDB_ERR_NOENTRY;
|
||||||
goto out;
|
goto out;
|
||||||
|
} else {
|
||||||
|
/* Success: record what the keytab returned for inspection */
|
||||||
|
{
|
||||||
|
char *entry_princ = NULL;
|
||||||
|
if (krb5_unparse_name(context, ktentry.principal, &entry_princ) == 0) {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: krb5_kt_get_entry succeeded: entry_principal=%s vno=%d enctype=%d keytab=%s",
|
||||||
|
entry_princ ? entry_princ : "<unparsed>",
|
||||||
|
ktentry.vno,
|
||||||
|
ktentry.keyblock.keytype,
|
||||||
|
k->path ? k->path : "<unknown>");
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: krb5_kt_get_entry succeeded: entry_principal=<unparsed> vno=%d enctype=%d keytab=%s",
|
||||||
|
ktentry.vno,
|
||||||
|
ktentry.keyblock.keytype,
|
||||||
|
k->path ? k->path : "<unknown>");
|
||||||
|
}
|
||||||
|
free(entry_princ);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_copy_principal(context, principal, &entry->principal);
|
ret = krb5_copy_principal(context, principal, &entry->principal);
|
||||||
|
|||||||
@@ -169,15 +169,12 @@ fuzz_jose_SOURCES = fuzz_jose.c
|
|||||||
fuzz_jose_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/base/libheimbase.la
|
fuzz_jose_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/base/libheimbase.la
|
||||||
fuzz_jose.$(OBJEXT): $(HX509_PROTOS) $(nodist_include_HEADERS)
|
fuzz_jose.$(OBJEXT): $(HX509_PROTOS) $(nodist_include_HEADERS)
|
||||||
test_expr_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/asn1/libasn1.la
|
test_expr_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/asn1/libasn1.la
|
||||||
test_cert_binary_CPPFLAGS = $(AM_CPPFLAGS) -DSRCDIR=\"$(srcdir)\"
|
|
||||||
test_cert_binary_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/asn1/libasn1.la
|
|
||||||
|
|
||||||
TESTS = $(SCRIPT_TESTS) $(PROGRAM_TESTS)
|
TESTS = $(SCRIPT_TESTS) $(PROGRAM_TESTS)
|
||||||
|
|
||||||
PROGRAM_TESTS = \
|
PROGRAM_TESTS = \
|
||||||
test_name \
|
test_name \
|
||||||
test_expr \
|
test_expr
|
||||||
test_cert_binary
|
|
||||||
|
|
||||||
SCRIPT_TESTS = \
|
SCRIPT_TESTS = \
|
||||||
test_ca \
|
test_ca \
|
||||||
@@ -339,7 +336,6 @@ EXTRA_DIST = \
|
|||||||
data/key2.der \
|
data/key2.der \
|
||||||
data/nist-data \
|
data/nist-data \
|
||||||
data/nist-data2 \
|
data/nist-data2 \
|
||||||
data/notafter-2338.pem \
|
|
||||||
data/no-proxy-test.crt \
|
data/no-proxy-test.crt \
|
||||||
data/no-proxy-test.key \
|
data/no-proxy-test.key \
|
||||||
data/ocsp-req1.der \
|
data/ocsp-req1.der \
|
||||||
|
|||||||
+2
-14
@@ -66,18 +66,6 @@ struct hx509_ca_tbs {
|
|||||||
AlgorithmIdentifier *sigalg;
|
AlgorithmIdentifier *sigalg;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
|
||||||
use_utc_time(time_t t)
|
|
||||||
{
|
|
||||||
if (t < 1)
|
|
||||||
return 1;
|
|
||||||
#if SIZEOF_TIME_T > 4 || defined(TIME_T_UNSIGNED)
|
|
||||||
if ((uint64_t)t >= 2524608000ULL)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate an to-be-signed certificate object that will be converted
|
* Allocate an to-be-signed certificate object that will be converted
|
||||||
* into an certificate.
|
* into an certificate.
|
||||||
@@ -1785,13 +1773,13 @@ ca_sign(hx509_context context,
|
|||||||
*
|
*
|
||||||
* Both, ...u.generalTime and ...u..utcTime are time_t.
|
* Both, ...u.generalTime and ...u..utcTime are time_t.
|
||||||
*/
|
*/
|
||||||
if (use_utc_time(notBefore))
|
if (notBefore < 1 || (int64_t)notBefore < 2524608000)
|
||||||
tbsc->validity.notBefore.element = choice_Time_utcTime;
|
tbsc->validity.notBefore.element = choice_Time_utcTime;
|
||||||
else
|
else
|
||||||
tbsc->validity.notBefore.element = choice_Time_generalTime;
|
tbsc->validity.notBefore.element = choice_Time_generalTime;
|
||||||
tbsc->validity.notBefore.u.generalTime = notBefore;
|
tbsc->validity.notBefore.u.generalTime = notBefore;
|
||||||
|
|
||||||
if (use_utc_time(notAfter))
|
if (notAfter < 1 || (int64_t)notAfter < 2524608000)
|
||||||
tbsc->validity.notAfter.element = choice_Time_utcTime;
|
tbsc->validity.notAfter.element = choice_Time_utcTime;
|
||||||
else
|
else
|
||||||
tbsc->validity.notAfter.element = choice_Time_generalTime;
|
tbsc->validity.notAfter.element = choice_Time_generalTime;
|
||||||
|
|||||||
+1
-38
@@ -78,7 +78,6 @@ struct hx509_cert_data {
|
|||||||
unsigned int ref;
|
unsigned int ref;
|
||||||
char *friendlyname;
|
char *friendlyname;
|
||||||
Certificate *data;
|
Certificate *data;
|
||||||
heim_octet_string encoding;
|
|
||||||
hx509_private_key private_key;
|
hx509_private_key private_key;
|
||||||
struct _hx509_cert_attrs attrs;
|
struct _hx509_cert_attrs attrs;
|
||||||
hx509_name basename;
|
hx509_name basename;
|
||||||
@@ -636,8 +635,6 @@ cert_init(hx509_context context, heim_error_t *error)
|
|||||||
cert->release = NULL;
|
cert->release = NULL;
|
||||||
cert->ctx = NULL;
|
cert->ctx = NULL;
|
||||||
cert->data= NULL;
|
cert->data= NULL;
|
||||||
cert->encoding.data = NULL;
|
|
||||||
cert->encoding.length = 0;
|
|
||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,23 +693,7 @@ hx509_cert_copy_no_private_key(hx509_context context,
|
|||||||
hx509_cert src,
|
hx509_cert src,
|
||||||
heim_error_t *error)
|
heim_error_t *error)
|
||||||
{
|
{
|
||||||
hx509_cert cert;
|
return hx509_cert_init(context, src->data, error);
|
||||||
int ret;
|
|
||||||
|
|
||||||
cert = hx509_cert_init(context, src->data, error);
|
|
||||||
if (cert == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret = der_copy_octet_string(&src->encoding, &cert->encoding);
|
|
||||||
if (ret) {
|
|
||||||
hx509_cert_free(cert);
|
|
||||||
if (error)
|
|
||||||
*error = heim_error_create_enomem();
|
|
||||||
errno = ret;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cert;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -766,7 +747,6 @@ hx509_cert_init_data(hx509_context context,
|
|||||||
heim_error_t *error)
|
heim_error_t *error)
|
||||||
{
|
{
|
||||||
hx509_cert cert;
|
hx509_cert cert;
|
||||||
heim_octet_string os;
|
|
||||||
Certificate t;
|
Certificate t;
|
||||||
size_t size;
|
size_t size;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -789,19 +769,6 @@ hx509_cert_init_data(hx509_context context,
|
|||||||
|
|
||||||
cert = hx509_cert_init(context, &t, error);
|
cert = hx509_cert_init(context, &t, error);
|
||||||
free_Certificate(&t);
|
free_Certificate(&t);
|
||||||
if (cert == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
os.length = len;
|
|
||||||
os.data = rk_UNCONST(ptr);
|
|
||||||
ret = der_copy_octet_string(&os, &cert->encoding);
|
|
||||||
if (ret) {
|
|
||||||
hx509_cert_free(cert);
|
|
||||||
if (error)
|
|
||||||
*error = heim_error_create_enomem();
|
|
||||||
errno = ret;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -857,7 +824,6 @@ hx509_cert_free(hx509_cert cert)
|
|||||||
if (cert->data)
|
if (cert->data)
|
||||||
free_Certificate(cert->data);
|
free_Certificate(cert->data);
|
||||||
free(cert->data);
|
free(cert->data);
|
||||||
der_free_octet_string(&cert->encoding);
|
|
||||||
|
|
||||||
for (i = 0; i < cert->attrs.len; i++) {
|
for (i = 0; i < cert->attrs.len; i++) {
|
||||||
der_free_octet_string(&cert->attrs.val[i]->data);
|
der_free_octet_string(&cert->attrs.val[i]->data);
|
||||||
@@ -4091,9 +4057,6 @@ hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os)
|
|||||||
os->data = NULL;
|
os->data = NULL;
|
||||||
os->length = 0;
|
os->length = 0;
|
||||||
|
|
||||||
if (c->encoding.data != NULL)
|
|
||||||
return der_copy_octet_string(&c->encoding, os);
|
|
||||||
|
|
||||||
ASN1_MALLOC_ENCODE(Certificate, os->data, os->length,
|
ASN1_MALLOC_ENCODE(Certificate, os->data, os->length,
|
||||||
_hx509_get_cert(c), &size, ret);
|
_hx509_get_cert(c), &size, ret);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFATCCAumgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAqMRswGQYDVQQDDBJoeDUwOSBUZXN0IFJv
|
|
||||||
b3QgQ0ExCzAJBgNVBAYTAlNFMCAXDTE5MDMyMjIyMjUwMloYDzIzMzgwMTE5MDMxNDA4WjAhMQsw
|
|
||||||
CQYDVQQGEwJTRTESMBAGA1UEAwwJVGVzdCBjZXJ0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
|
||||||
CgKCAgEA2h1NylGd8Z/XpHpF+HWYZrLFfVPeQjV0gc0en/ND16eDf/uizjxEN4BPITam9slRdJ7i
|
|
||||||
m7+t5OtyEWQ2iLOpkWPH7jjE9YwGceUJt+tXXb/bW3IHxSnobzOzoifvH1DwVTNjQSPgsvchd0ur
|
|
||||||
nXMqu7ZOiH985cY3PrYgwVc+bVd47w1H6UHn+rYtMj9CBY1Wr/XEuG6ZGucH1aE/KX3OsjmmqwZ6
|
|
||||||
4iY52JaeO8iveT6aJE5Lsq/kBw5x3C9wJ5c8ovppm1dLxVNeKAywx1cforImD1+/00V4kFos/Gpn
|
|
||||||
M7bBfs0XwFieuoXFFVpaZ9u/LwXNONmUyZV/m2iwYv83ks/Yd77Lcj0PuYBEV8DJEAH9ByUw69hI
|
|
||||||
Ba+Y+sRkbVmmao0b1EvzB5ho47tZySH4EbSighsN6IzgpeEcccrDLZBDw+6ZLH1BSDnIAHINgDkj
|
|
||||||
oTon7QfKMo80yrudZxN9Me1K2zV6zrOJ42SdPkdO07e9qxIWELtm6Bp3TCrguRZpZhSDTkrzb6uF
|
|
||||||
anDGm86Tq3U2o6Wqn0XWon8Xx2/59ec1UaV1xQe+Js57Pyk6dGsXeU7PTAppdVjb66jd8ebMoxhT
|
|
||||||
pcWlWqHPN2qxn9PU6w8CQNKuaM68xUbj7viXiO7IpwF6oSOv8zEsKm8Sd9w8UZ1A9Joqe4UpHz7D
|
|
||||||
1TeObgkCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFBv07DRCuotn
|
|
||||||
rFXyN120aKnYXlh7MA0GCSqGSIb3DQEBBQUAA4ICAQCV9xyZckJP0726P3p1uwE6rc5re7c9XTtG
|
|
||||||
UeqaNpRwNhw7/Lqdiw1ENgitpnOCvCPt+VoJj51iEcGUfGFmH4u5Ctw6tesiVN6j5YqUEB+EUm3+
|
|
||||||
J8jly6WOqYMWlQ1sPleF4eyCBUdtKK0NhPpAoJb0hKrR4Qu3keJHTwWX+BCg6Fe97UhlVXXa5TTo
|
|
||||||
8SCV1kCMQr+02VXIMOjVztgdMGWQOevig+0RA80HwOHEkYSgl45tIuZ1dyF8MotI7dayGS6vJq19
|
|
||||||
bM4J4Xi2cmFgIpK430JrNGtfNe/x08Z/kgU80Ah3AWb3V7hl3tPSsb+TsYyjJ+bU4iubzZ2+MYJb
|
|
||||||
U91avTkFX4xW8n+bt+/mB5a/itmNu2KYht6qkcP+57unH/D9H2ymBATwwlGhkYya7vmHQjd+nCdy
|
|
||||||
WdxgqI7RgZfxFcPYqU6aCemBdjk2swih5V6XN7pDjwYacGk7/nmmXi0mBOm8X1fJ0IDCDUvHDt0E
|
|
||||||
5RVJndf/7qMcBFZ94qDTORpZvYWw61TqgYvhF5Sl/uMM0HRC7kr0ZpBJS2S8RzX1smCOdAXQptKU
|
|
||||||
tOAPSz816irgJFjBbtBlblj34ZACrkAjJemAmtKn6l38bfhFD9tTkVUyRuNqwFQKWkzoGh6mMz7+
|
|
||||||
7batz2o8L7JsR3XxKUMxacMMQlZb2biZe/8rUIc0Lg==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -47,23 +47,6 @@ for a in $srcdir/data/*.crt; do
|
|||||||
${hxtool} print --content FILE:"$a" > /dev/null 2>/dev/null
|
${hxtool} print --content FILE:"$a" > /dev/null 2>/dev/null
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "print certificate with 2338 notAfter"
|
|
||||||
${hxtool} print --content FILE:$srcdir/data/notafter-2338.pem > cert-2338.tmp || exit 1
|
|
||||||
config=$objdir/../../include/config.h
|
|
||||||
if grep '^#define SIZEOF_TIME_T 4$' "$config" > /dev/null; then
|
|
||||||
if grep '^#define TIME_T_UNSIGNED' "$config" > /dev/null; then
|
|
||||||
notafter='notAfter 2106-02-07 06:28:15'
|
|
||||||
else
|
|
||||||
notafter='notAfter 2038-01-19 03:14:07'
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
notafter='notAfter 2338-01-19 03:14:08'
|
|
||||||
fi
|
|
||||||
grep "$notafter" cert-2338.tmp > /dev/null || {
|
|
||||||
cat cert-2338.tmp
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "print NULL"
|
echo "print NULL"
|
||||||
${hxtool} print --content NULL: > /dev/null || exit 1
|
${hxtool} print --content NULL: > /dev/null || exit 1
|
||||||
|
|
||||||
|
|||||||
@@ -1,179 +0,0 @@
|
|||||||
#include "hx_locl.h"
|
|
||||||
#include <err.h>
|
|
||||||
|
|
||||||
#ifndef SRCDIR
|
|
||||||
#define SRCDIR "."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct pem_cert {
|
|
||||||
heim_octet_string der;
|
|
||||||
int found;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
pem_cert_reader(hx509_context context, const char *type,
|
|
||||||
const hx509_pem_header *headers,
|
|
||||||
const void *data, size_t length, void *ctx)
|
|
||||||
{
|
|
||||||
struct pem_cert *pem = ctx;
|
|
||||||
|
|
||||||
(void)context;
|
|
||||||
(void)headers;
|
|
||||||
|
|
||||||
if (strcmp(type, "CERTIFICATE") != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (pem->found)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pem->der.data = malloc(length);
|
|
||||||
if (pem->der.data == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
memcpy(pem->der.data, data, length);
|
|
||||||
pem->der.length = length;
|
|
||||||
pem->found = 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
read_cert_der(hx509_context context, const char *path, heim_octet_string *der)
|
|
||||||
{
|
|
||||||
struct pem_cert pem;
|
|
||||||
FILE *f;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(&pem, 0, sizeof(pem));
|
|
||||||
|
|
||||||
f = fopen(path, "r");
|
|
||||||
if (f == NULL)
|
|
||||||
err(1, "fopen: %s", path);
|
|
||||||
|
|
||||||
ret = hx509_pem_read(context, f, pem_cert_reader, &pem);
|
|
||||||
fclose(f);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_pem_read: %s", path);
|
|
||||||
if (!pem.found)
|
|
||||||
errx(1, "did not find a certificate in %s", path);
|
|
||||||
|
|
||||||
*der = pem.der;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
compare_octet_string(const char *what,
|
|
||||||
const heim_octet_string *expected,
|
|
||||||
const heim_octet_string *actual)
|
|
||||||
{
|
|
||||||
if (actual->length != expected->length)
|
|
||||||
errx(1, "%s length changed from %lu to %lu",
|
|
||||||
what, (unsigned long)expected->length,
|
|
||||||
(unsigned long)actual->length);
|
|
||||||
if (memcmp(actual->data, expected->data, expected->length) != 0)
|
|
||||||
errx(1, "%s data changed", what);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_cert_binary(hx509_context context, const heim_octet_string *der)
|
|
||||||
{
|
|
||||||
heim_octet_string os;
|
|
||||||
hx509_cert cert;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(&os, 0, sizeof(os));
|
|
||||||
|
|
||||||
cert = hx509_cert_init_data(context, der->data, der->length, NULL);
|
|
||||||
if (cert == NULL)
|
|
||||||
err(1, "hx509_cert_init_data");
|
|
||||||
|
|
||||||
ret = hx509_cert_binary(context, cert, &os);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_cert_binary");
|
|
||||||
compare_octet_string("certificate encoding", der, &os);
|
|
||||||
der_free_octet_string(&os);
|
|
||||||
|
|
||||||
hx509_cert_free(cert);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
make_store_name(void)
|
|
||||||
{
|
|
||||||
char *store_name = NULL;
|
|
||||||
|
|
||||||
if (asprintf(&store_name, "FILE:%s/data/test.crt,%s/data/test.key",
|
|
||||||
SRCDIR, SRCDIR) == -1 || store_name == NULL)
|
|
||||||
err(1, "asprintf");
|
|
||||||
|
|
||||||
return store_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_keyless_store_cert_encoding(hx509_context context,
|
|
||||||
const heim_octet_string *der)
|
|
||||||
{
|
|
||||||
heim_octet_string os;
|
|
||||||
hx509_certs certs = NULL;
|
|
||||||
hx509_cert cert = NULL;
|
|
||||||
char *store_name;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(&os, 0, sizeof(os));
|
|
||||||
|
|
||||||
ret = hx509_certs_init(context, "MEMORY:test-keyless-certs",
|
|
||||||
HX509_CERTS_NO_PRIVATE_KEYS, NULL, &certs);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_certs_init");
|
|
||||||
|
|
||||||
store_name = make_store_name();
|
|
||||||
ret = hx509_certs_append(context, certs, NULL, store_name);
|
|
||||||
free(store_name);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_certs_append");
|
|
||||||
|
|
||||||
ret = hx509_get_one_cert(context, certs, &cert);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_get_one_cert");
|
|
||||||
if (hx509_cert_have_private_key(cert))
|
|
||||||
errx(1, "HX509_CERTS_NO_PRIVATE_KEYS store kept a private key");
|
|
||||||
|
|
||||||
ret = hx509_cert_binary(context, cert, &os);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_cert_binary on keyless cert");
|
|
||||||
compare_octet_string("keyless store certificate encoding", der, &os);
|
|
||||||
|
|
||||||
der_free_octet_string(&os);
|
|
||||||
hx509_cert_free(cert);
|
|
||||||
hx509_certs_free(&certs);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
heim_octet_string der;
|
|
||||||
hx509_context context;
|
|
||||||
char *cert_path = NULL;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
|
|
||||||
memset(&der, 0, sizeof(der));
|
|
||||||
|
|
||||||
ret = hx509_context_init(&context);
|
|
||||||
if (ret)
|
|
||||||
errx(1, "hx509_context_init failed with %d", ret);
|
|
||||||
|
|
||||||
if (asprintf(&cert_path, "%s/data/test.crt", SRCDIR) == -1 ||
|
|
||||||
cert_path == NULL)
|
|
||||||
err(1, "asprintf");
|
|
||||||
|
|
||||||
read_cert_der(context, cert_path, &der);
|
|
||||||
free(cert_path);
|
|
||||||
|
|
||||||
check_cert_binary(context, &der);
|
|
||||||
check_keyless_store_cert_encoding(context, &der);
|
|
||||||
|
|
||||||
der_free_octet_string(&der);
|
|
||||||
hx509_context_free(&context);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+3
-13
@@ -46,23 +46,14 @@ if have_gcd
|
|||||||
# stops building on recent OS X releases unless we disable this warning.
|
# stops building on recent OS X releases unless we disable this warning.
|
||||||
WFLAGS += -Wno-deprecated-declarations
|
WFLAGS += -Wno-deprecated-declarations
|
||||||
|
|
||||||
heim_ipc.stamp: heim_ipc.defs
|
heim_ipc.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.defs
|
||||||
mig -header heim_ipc.h -user heim_ipcUser.c -sheader heim_ipcServer.h -server heim_ipcServer.c -I$(srcdir) $(srcdir)/heim_ipc.defs
|
mig -header heim_ipc.h -user heim_ipcUser.c -sheader heim_ipcServer.h -server heim_ipcServer.c -I$(srcdir) $(srcdir)/heim_ipc.defs
|
||||||
touch $@
|
|
||||||
|
|
||||||
heim_ipc.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.stamp
|
heim_ipc_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.defs
|
||||||
|
|
||||||
heim_ipc_async.stamp: heim_ipc_async.defs
|
|
||||||
mig -header heim_ipc_async.h -user heim_ipc_asyncUser.c -sheader heim_ipc_asyncServer.h -server heim_ipc_asyncServer.c -I$(srcdir) $(srcdir)/heim_ipc_async.defs
|
mig -header heim_ipc_async.h -user heim_ipc_asyncUser.c -sheader heim_ipc_asyncServer.h -server heim_ipc_asyncServer.c -I$(srcdir) $(srcdir)/heim_ipc_async.defs
|
||||||
touch $@
|
|
||||||
|
|
||||||
heim_ipc_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.stamp
|
heim_ipc_reply.h heim_ipc_replyUser.c: heim_ipc_reply.defs
|
||||||
|
|
||||||
heim_ipc_reply.stamp: heim_ipc_reply.defs
|
|
||||||
mig -header heim_ipc_reply.h -user heim_ipc_replyUser.c -sheader /dev/null -server /dev/null -I$(srcdir) $(srcdir)/heim_ipc_reply.defs
|
mig -header heim_ipc_reply.h -user heim_ipc_replyUser.c -sheader /dev/null -server /dev/null -I$(srcdir) $(srcdir)/heim_ipc_reply.defs
|
||||||
touch $@
|
|
||||||
|
|
||||||
heim_ipc_reply.h heim_ipc_replyUser.c: heim_ipc_reply.stamp
|
|
||||||
|
|
||||||
built_ipcc = heim_ipc.h heim_ipcUser.c
|
built_ipcc = heim_ipc.h heim_ipcUser.c
|
||||||
built_ipcc += heim_ipc_asyncServer.c heim_ipc_asyncServer.h
|
built_ipcc += heim_ipc_asyncServer.c heim_ipc_asyncServer.h
|
||||||
@@ -78,7 +69,6 @@ nodist_libheim_ipcs_la_SOURCES = $(built_ipcs)
|
|||||||
libheim_ipcs_la_LIBADD += -lbsm
|
libheim_ipcs_la_LIBADD += -lbsm
|
||||||
|
|
||||||
CLEANFILES = $(built_ipcc) $(built_ipcs)
|
CLEANFILES = $(built_ipcc) $(built_ipcs)
|
||||||
CLEANFILES += heim_ipc.stamp heim_ipc_async.stamp heim_ipc_reply.stamp
|
|
||||||
|
|
||||||
$(srcdir)/client.c: $(built_ipcc)
|
$(srcdir)/client.c: $(built_ipcc)
|
||||||
$(srcdir)/server.c: $(built_ipcs)
|
$(srcdir)/server.c: $(built_ipcs)
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
@@ -53,17 +53,6 @@
|
|||||||
#define LOG_VERSION_FIRST 1
|
#define LOG_VERSION_FIRST 1
|
||||||
#define LOG_VERSION_UBER 0
|
#define LOG_VERSION_UBER 0
|
||||||
|
|
||||||
#define LOG_HEADER_SZ ((off_t)(sizeof(uint32_t) * 4))
|
|
||||||
#define LOG_TRAILER_SZ ((off_t)(sizeof(uint32_t) * 2))
|
|
||||||
#define LOG_WRAPPER_SZ ((off_t)(LOG_HEADER_SZ + LOG_TRAILER_SZ))
|
|
||||||
#define LOG_UBER_LEN ((off_t)(sizeof(uint64_t) + sizeof(uint32_t) * 2))
|
|
||||||
#define LOG_UBER_SZ ((off_t)(LOG_WRAPPER_SZ + LOG_UBER_LEN))
|
|
||||||
|
|
||||||
struct kadm5_log_snap {
|
|
||||||
char bytes;
|
|
||||||
char buf[LOG_UBER_SZ + LOG_HEADER_SZ];
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <krb5.h>
|
#include <krb5.h>
|
||||||
|
|
||||||
#define KRB5_KDB_DISALLOW_POSTDATED 0x00000001
|
#define KRB5_KDB_DISALLOW_POSTDATED 0x00000001
|
||||||
|
|||||||
+151
-19
@@ -191,6 +191,20 @@ _kadm5_c_init_context(kadm5_client_context **ctx,
|
|||||||
}
|
}
|
||||||
if ((*ctx)->readonly_kadmind_port == 0)
|
if ((*ctx)->readonly_kadmind_port == 0)
|
||||||
(*ctx)->readonly_kadmind_port = (*ctx)->kadmind_port;
|
(*ctx)->readonly_kadmind_port = (*ctx)->kadmind_port;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: emit context-level info to help trace client init-time
|
||||||
|
* decisions in test logs.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context,
|
||||||
|
"_kadm5_c_init_context: realm=%s admin_server=%s readonly_admin_server=%s kadmind_port=%u readonly_port=%u (pid=%d)",
|
||||||
|
(*ctx)->realm ? (*ctx)->realm : "<null>",
|
||||||
|
(*ctx)->admin_server ? (*ctx)->admin_server : "<null>",
|
||||||
|
(*ctx)->readonly_admin_server ? (*ctx)->readonly_admin_server : "<null>",
|
||||||
|
(unsigned)ntohs((*ctx)->kadmind_port),
|
||||||
|
(unsigned)ntohs((*ctx)->readonly_kadmind_port),
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,10 +217,12 @@ kadm5_c_dup_context(void *vin, void **out)
|
|||||||
kadm5_client_context *ctx;
|
kadm5_client_context *ctx;
|
||||||
|
|
||||||
*out = NULL;
|
*out = NULL;
|
||||||
ctx = calloc(1, sizeof(*ctx));
|
ctx = malloc(sizeof(*ctx));
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return krb5_enomem(in->context);
|
return krb5_enomem(in->context);
|
||||||
|
|
||||||
|
|
||||||
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
set_funcs(ctx);
|
set_funcs(ctx);
|
||||||
ctx->readonly_kadmind_port = in->readonly_kadmind_port;
|
ctx->readonly_kadmind_port = in->readonly_kadmind_port;
|
||||||
ctx->kadmind_port = in->kadmind_port;
|
ctx->kadmind_port = in->kadmind_port;
|
||||||
@@ -224,13 +240,18 @@ kadm5_c_dup_context(void *vin, void **out)
|
|||||||
if (in->readonly_admin_server &&
|
if (in->readonly_admin_server &&
|
||||||
(ctx->readonly_admin_server = strdup(in->readonly_admin_server)) == NULL)
|
(ctx->readonly_admin_server = strdup(in->readonly_admin_server)) == NULL)
|
||||||
ret = krb5_enomem(context);
|
ret = krb5_enomem(context);
|
||||||
if (in->client_name != NULL &&
|
|
||||||
(ctx->client_name = strdup(in->client_name)) == NULL)
|
/* Preserve client identity and prompter behavior in duplicated context */
|
||||||
|
if (in->client_name && (ctx->client_name = strdup(in->client_name)) == NULL)
|
||||||
ret = krb5_enomem(context);
|
ret = krb5_enomem(context);
|
||||||
if (in->keytab && (ctx->keytab = strdup(in->keytab)) == NULL)
|
if (in->service_name && (ctx->service_name = strdup(in->service_name)) == NULL)
|
||||||
ret = krb5_enomem(context);
|
ret = krb5_enomem(context);
|
||||||
|
/* Copy the prompter pointer so duplicated contexts behave the same
|
||||||
|
with respect to prompting vs keytab-based auth. */
|
||||||
ctx->prompter = in->prompter;
|
ctx->prompter = in->prompter;
|
||||||
|
|
||||||
|
if (in->keytab && (ctx->keytab = strdup(in->keytab)) == NULL)
|
||||||
|
ret = krb5_enomem(context);
|
||||||
if (in->ccache) {
|
if (in->ccache) {
|
||||||
char *fullname = NULL;
|
char *fullname = NULL;
|
||||||
|
|
||||||
@@ -295,7 +316,24 @@ get_new_cache(krb5_context context,
|
|||||||
krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
|
krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
|
||||||
krb5_get_init_creds_opt_set_proxiable (opt, FALSE);
|
krb5_get_init_creds_opt_set_proxiable (opt, FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: record the inputs to credential selection so tests can
|
||||||
|
* observe why keytab vs password paths were chosen.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context,
|
||||||
|
"get_new_cache: entry client=%s password_provided=%d prompter=%p keytab=%s server_name=%s (pid=%d)",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>",
|
||||||
|
password ? 1 : 0,
|
||||||
|
(void *)prompter,
|
||||||
|
keytab ? keytab : "<default>",
|
||||||
|
server_name ? server_name : "<null>",
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
if(password == NULL && prompter == NULL) {
|
if(password == NULL && prompter == NULL) {
|
||||||
|
/* Debug: choosing keytab-based initial credentials */
|
||||||
|
krb5_warnx(context, "get_new_cache: choosing keytab auth (keytab=%s, client=%s)",
|
||||||
|
keytab ? keytab : "<default>",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
krb5_keytab kt;
|
krb5_keytab kt;
|
||||||
if(keytab == NULL)
|
if(keytab == NULL)
|
||||||
ret = krb5_kt_default(context, &kt);
|
ret = krb5_kt_default(context, &kt);
|
||||||
@@ -312,8 +350,21 @@ get_new_cache(krb5_context context,
|
|||||||
0,
|
0,
|
||||||
server_name,
|
server_name,
|
||||||
opt);
|
opt);
|
||||||
|
/* Log success/failure of keytab credential attempt for diagnostics */
|
||||||
|
if (ret == 0) {
|
||||||
|
krb5_warnx(context, "get_new_cache: krb5_get_init_creds_keytab succeeded for principal=%s using keytab=%s",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>",
|
||||||
|
keytab ? keytab : "<default>");
|
||||||
|
} else {
|
||||||
|
krb5_warn(context, ret, "get_new_cache: krb5_get_init_creds_keytab failed (keytab=%s)", keytab ? keytab : "<default>");
|
||||||
|
}
|
||||||
krb5_kt_close(context, kt);
|
krb5_kt_close(context, kt);
|
||||||
} else {
|
} else {
|
||||||
|
/* Debug: choosing password-based initial credentials */
|
||||||
|
krb5_warnx(context, "get_new_cache: choosing password auth (password_provided=%d prompter=%p client=%s)",
|
||||||
|
password ? 1 : 0,
|
||||||
|
(void *)prompter,
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
ret = krb5_get_init_creds_password (context,
|
ret = krb5_get_init_creds_password (context,
|
||||||
&cred,
|
&cred,
|
||||||
client,
|
client,
|
||||||
@@ -323,6 +374,13 @@ get_new_cache(krb5_context context,
|
|||||||
0,
|
0,
|
||||||
server_name,
|
server_name,
|
||||||
opt);
|
opt);
|
||||||
|
if (ret == 0) {
|
||||||
|
krb5_warnx(context, "get_new_cache: krb5_get_init_creds_password succeeded for principal=%s",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
|
} else {
|
||||||
|
krb5_warn(context, ret, "get_new_cache: krb5_get_init_creds_password failed for principal=%s",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
krb5_get_init_creds_opt_free(context, opt);
|
krb5_get_init_creds_opt_free(context, opt);
|
||||||
switch(ret){
|
switch(ret){
|
||||||
@@ -451,6 +509,27 @@ _kadm5_c_get_cred_cache(krb5_context context,
|
|||||||
if(server_name == NULL)
|
if(server_name == NULL)
|
||||||
server_name = KADM5_ADMIN_SERVICE;
|
server_name = KADM5_ADMIN_SERVICE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: log the invocation and environment so we can correlate
|
||||||
|
* with test harness behavior (e.g. whether KRB5_KTNAME / KRB5CCNAME
|
||||||
|
* were set).
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
const char *env_kt = secure_getenv ? secure_getenv("KRB5_KTNAME") : getenv("KRB5_KTNAME");
|
||||||
|
const char *env_cc = secure_getenv ? secure_getenv("KRB5CCNAME") : getenv("KRB5CCNAME");
|
||||||
|
krb5_warnx(context,
|
||||||
|
"_kadm5_c_get_cred_cache: called client_name=%s server_name=%s password_provided=%d prompter=%p keytab=%s ccache=%p env.KRB5_KTNAME=%s env.KRB5CCNAME=%s (pid=%d)",
|
||||||
|
client_name ? client_name : "<null>",
|
||||||
|
server_name ? server_name : "<null>",
|
||||||
|
password ? 1 : 0,
|
||||||
|
(void *)prompter,
|
||||||
|
keytab ? keytab : "<null>",
|
||||||
|
(void *)ccache,
|
||||||
|
env_kt ? env_kt : "<unset>",
|
||||||
|
env_cc ? env_cc : "<unset>",
|
||||||
|
(int)getpid());
|
||||||
|
}
|
||||||
|
|
||||||
if(client_name != NULL) {
|
if(client_name != NULL) {
|
||||||
ret = krb5_parse_name(context, client_name, &client);
|
ret = krb5_parse_name(context, client_name, &client);
|
||||||
if(ret)
|
if(ret)
|
||||||
@@ -458,17 +537,7 @@ _kadm5_c_get_cred_cache(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ccache != NULL) {
|
if(ccache != NULL) {
|
||||||
char *fullname = NULL;
|
id = ccache;
|
||||||
|
|
||||||
ret = krb5_cc_get_full_name(context, ccache, &fullname);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = krb5_cc_resolve(context, fullname, &id);
|
|
||||||
free(fullname);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = krb5_cc_get_principal(context, id, &client);
|
ret = krb5_cc_get_principal(context, id, &client);
|
||||||
if(ret)
|
if(ret)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -515,26 +584,47 @@ _kadm5_c_get_cred_cache(krb5_context context,
|
|||||||
|
|
||||||
if(id && client && (default_client == NULL ||
|
if(id && client && (default_client == NULL ||
|
||||||
krb5_principal_compare(context, client, default_client) != 0)) {
|
krb5_principal_compare(context, client, default_client) != 0)) {
|
||||||
|
/* Debug: attempting to obtain kadmin ticket from existing credential cache */
|
||||||
|
krb5_warnx(context, "_kadm5_c_get_cred_cache: trying credential cache to get kadmin ticket (client=%s)",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
ret = get_kadm_ticket(context, id, client, server_name);
|
ret = get_kadm_ticket(context, id, client, server_name);
|
||||||
if(ret == 0) {
|
if(ret == 0) {
|
||||||
|
krb5_warnx(context, "_kadm5_c_get_cred_cache: got kadmin ticket from cache for client=%s",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
*ret_cache = id;
|
*ret_cache = id;
|
||||||
krb5_free_principal(context, default_client);
|
krb5_free_principal(context, default_client);
|
||||||
if (default_client != client)
|
if (default_client != client)
|
||||||
krb5_free_principal(context, client);
|
krb5_free_principal(context, client);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
krb5_warn(context, ret, "_kadm5_c_get_cred_cache: get_kadm_ticket from cache failed for client=%s", client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
if(ccache != NULL)
|
if(ccache != NULL)
|
||||||
/* couldn't get ticket from cache */
|
/* couldn't get ticket from cache */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* get creds via AS request */
|
/* get creds via AS request */
|
||||||
if (id)
|
if(id && (id != ccache))
|
||||||
krb5_cc_close(context, id);
|
krb5_cc_close(context, id);
|
||||||
if (client != default_client)
|
if (client != default_client)
|
||||||
krb5_free_principal(context, default_client);
|
krb5_free_principal(context, default_client);
|
||||||
|
|
||||||
ret = get_new_cache(context, client, password, prompter, keytab,
|
ret = get_new_cache(context, client, password, prompter, keytab,
|
||||||
server_name, ret_cache);
|
server_name, ret_cache);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: report the result of get_new_cache so caller logs
|
||||||
|
* can show why auth succeeded/failed.
|
||||||
|
*/
|
||||||
|
if (ret == 0) {
|
||||||
|
krb5_warnx(context, "_kadm5_c_get_cred_cache: get_new_cache succeeded for client=%s (pid=%d)",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>",
|
||||||
|
(int)getpid());
|
||||||
|
} else {
|
||||||
|
krb5_warn(context, ret, "_kadm5_c_get_cred_cache: get_new_cache failed for client=%s (pid=%d)",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>",
|
||||||
|
(int)getpid());
|
||||||
|
}
|
||||||
|
|
||||||
krb5_free_principal(context, client);
|
krb5_free_principal(context, client);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -558,6 +648,17 @@ kadm_connect(kadm5_client_context *ctx)
|
|||||||
krb5_context context = ctx->context;
|
krb5_context context = ctx->context;
|
||||||
int writable = 0;
|
int writable = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: record connect intent and client context pointers
|
||||||
|
* to help correlate kadmin network activity with credential selection.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context, "kadm_connect: entering (client_name=%s prompter=%p keytab=%s ccache=%p pid=%d)",
|
||||||
|
ctx->client_name ? ctx->client_name : "<null>",
|
||||||
|
(void *)ctx->prompter,
|
||||||
|
ctx->keytab ? ctx->keytab : "<null>",
|
||||||
|
(void *)ctx->ccache,
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
if (ctx->ac)
|
if (ctx->ac)
|
||||||
krb5_auth_con_free(context, ctx->ac);
|
krb5_auth_con_free(context, ctx->ac);
|
||||||
ctx->ac = NULL;
|
ctx->ac = NULL;
|
||||||
@@ -671,6 +772,12 @@ out:
|
|||||||
rk_closesocket(s);
|
rk_closesocket(s);
|
||||||
krb5_auth_con_free(context, ctx->ac);
|
krb5_auth_con_free(context, ctx->ac);
|
||||||
ctx->ac = NULL;
|
ctx->ac = NULL;
|
||||||
|
} else {
|
||||||
|
/* Extra debug: successful connect and auth */
|
||||||
|
krb5_warnx(context, "kadm_connect: success connected_to_writable=%d sock=%d (pid=%d)",
|
||||||
|
(int)ctx->connected_to_writable,
|
||||||
|
(int)ctx->sock,
|
||||||
|
(int)getpid());
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -717,12 +824,25 @@ kadm5_c_init_with_context(krb5_context context,
|
|||||||
kadm5_client_context *ctx = NULL;
|
kadm5_client_context *ctx = NULL;
|
||||||
krb5_ccache cc;
|
krb5_ccache cc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: record initialization flags and pointers so we can later
|
||||||
|
* understand whether a prompter was provided (which affects keytab vs
|
||||||
|
* password selection) and whether a keytab or ccache was requested.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context, "kadm5_c_init_with_context: client_name=%s password_provided=%d prompter=%p keytab=%s ccache=%p service_name=%s (pid=%d)",
|
||||||
|
client_name ? client_name : "<null>",
|
||||||
|
password ? 1 : 0,
|
||||||
|
(void *)prompter,
|
||||||
|
keytab ? keytab : "<null>",
|
||||||
|
(void *)ccache,
|
||||||
|
service_name ? service_name : "<null>",
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
ret = _kadm5_c_init_context(&ctx, realm_params, context);
|
ret = _kadm5_c_init_context(&ctx, realm_params, context);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((password != NULL && *password != '\0') ||
|
if (password != NULL && *password != '\0') {
|
||||||
(client_name && !keytab)) {
|
|
||||||
ret = _kadm5_c_get_cred_cache(context,
|
ret = _kadm5_c_get_cred_cache(context,
|
||||||
client_name,
|
client_name,
|
||||||
service_name,
|
service_name,
|
||||||
@@ -750,6 +870,19 @@ kadm5_c_init_with_context(krb5_context context,
|
|||||||
ctx->sock = -1;
|
ctx->sock = -1;
|
||||||
|
|
||||||
*server_handle = ctx;
|
*server_handle = ctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: final context values after init so logs show what the
|
||||||
|
* kadm client will carry into subsequent connect attempts.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context, "kadm5_c_init_with_context: done ctx=%p client_name=%s prompter=%p keytab=%s ccache=%p (pid=%d)",
|
||||||
|
(void *)ctx,
|
||||||
|
ctx->client_name ? ctx->client_name : "<null>",
|
||||||
|
(void *)ctx->prompter,
|
||||||
|
ctx->keytab ? ctx->keytab : "<null>",
|
||||||
|
(void *)ctx->ccache,
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,4 +1069,3 @@ kadm5_init(char *client_name, char *pass,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+172
-281
@@ -86,32 +86,8 @@ make_signal_socket (krb5_context context)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
listen_port(krb5_context context, const char *port_str)
|
|
||||||
{
|
|
||||||
int port;
|
|
||||||
|
|
||||||
if (port_str) {
|
|
||||||
port = krb5_getportbyname(context, port_str, "tcp", 0);
|
|
||||||
if (port == 0) {
|
|
||||||
char *ptr;
|
|
||||||
long num;
|
|
||||||
|
|
||||||
num = strtol(port_str, &ptr, 10);
|
|
||||||
if (num == 0 && ptr == port_str)
|
|
||||||
krb5_errx(context, 1, "bad port `%s'", port_str);
|
|
||||||
port = htons(num);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
port = krb5_getportbyname(context, IPROP_SERVICE,
|
|
||||||
"tcp", IPROP_PORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
static krb5_socket_t
|
static krb5_socket_t
|
||||||
make_listen_socket(krb5_context context, int port)
|
make_listen_socket (krb5_context context, const char *port_str)
|
||||||
{
|
{
|
||||||
krb5_socket_t fd;
|
krb5_socket_t fd;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
@@ -123,9 +99,24 @@ make_listen_socket(krb5_context context, int port)
|
|||||||
(void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
|
(void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
|
||||||
memset (&addr, 0, sizeof(addr));
|
memset (&addr, 0, sizeof(addr));
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = port;
|
|
||||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
|
|
||||||
|
if (port_str) {
|
||||||
|
addr.sin_port = krb5_getportbyname (context,
|
||||||
|
port_str, "tcp",
|
||||||
|
0);
|
||||||
|
if (addr.sin_port == 0) {
|
||||||
|
char *ptr;
|
||||||
|
long port;
|
||||||
|
|
||||||
|
port = strtol (port_str, &ptr, 10);
|
||||||
|
if (port == 0 && ptr == port_str)
|
||||||
|
krb5_errx (context, 1, "bad port `%s'", port_str);
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addr.sin_port = krb5_getportbyname (context, IPROP_SERVICE,
|
||||||
|
"tcp", IPROP_PORT);
|
||||||
|
}
|
||||||
if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
||||||
krb5_err (context, 1, errno, "bind");
|
krb5_err (context, 1, errno, "bind");
|
||||||
if (listen(fd, SOMAXCONN) < 0)
|
if (listen(fd, SOMAXCONN) < 0)
|
||||||
@@ -133,68 +124,15 @@ make_listen_socket(krb5_context context, int port)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AF_INET6
|
|
||||||
static krb5_socket_t
|
|
||||||
make_listen_socket6(krb5_context context, int port)
|
|
||||||
{
|
|
||||||
krb5_socket_t fd;
|
|
||||||
int one = 1;
|
|
||||||
struct sockaddr_in6 addr;
|
|
||||||
|
|
||||||
fd = socket(AF_INET6, SOCK_STREAM, 0);
|
|
||||||
if (rk_IS_BAD_SOCKET(fd)) {
|
|
||||||
#ifdef EAFNOSUPPORT
|
|
||||||
if (rk_SOCK_ERRNO != EAFNOSUPPORT)
|
|
||||||
#endif
|
|
||||||
krb5_warn(context, rk_SOCK_ERRNO, "socket AF_INET6");
|
|
||||||
return rk_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
(void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
|
|
||||||
socket_set_ipv6only(fd, 1);
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sin6_family = AF_INET6;
|
|
||||||
addr.sin6_port = port;
|
|
||||||
addr.sin6_addr = in6addr_any;
|
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
|
||||||
krb5_warn(context, errno, "bind AF_INET6");
|
|
||||||
rk_closesocket(fd);
|
|
||||||
return rk_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
if (listen(fd, SOMAXCONN) < 0) {
|
|
||||||
krb5_warn (context, errno, "listen AF_INET6");
|
|
||||||
rk_closesocket(fd);
|
|
||||||
return rk_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
make_listen_sockets(krb5_context context, const char *port_str,
|
|
||||||
krb5_socket_t *fds, int *num_fds)
|
|
||||||
{
|
|
||||||
krb5_socket_t fd;
|
|
||||||
int port = listen_port(context, port_str);
|
|
||||||
|
|
||||||
*num_fds = 0;
|
|
||||||
|
|
||||||
#ifdef AF_INET6
|
|
||||||
fd = make_listen_socket6(context, port);
|
|
||||||
if (!rk_IS_BAD_SOCKET(fd))
|
|
||||||
fds[(*num_fds)++] = fd;
|
|
||||||
#endif
|
|
||||||
fds[(*num_fds)++] = make_listen_socket(context, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct slave {
|
struct slave {
|
||||||
krb5_socket_t fd;
|
krb5_socket_t fd;
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_in addr;
|
||||||
char *name;
|
char *name;
|
||||||
krb5_auth_context ac;
|
krb5_auth_context ac;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t version_tstamp;
|
uint32_t version_tstamp;
|
||||||
|
uint32_t version_ack;
|
||||||
time_t seen;
|
time_t seen;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
#define SLAVE_F_DEAD 0x1
|
#define SLAVE_F_DEAD 0x1
|
||||||
@@ -438,6 +376,7 @@ add_slave (krb5_context context, krb5_keytab keytab, slave **root,
|
|||||||
krb5_warnx (context, "connection from %s", s->name);
|
krb5_warnx (context, "connection from %s", s->name);
|
||||||
|
|
||||||
s->version = 0;
|
s->version = 0;
|
||||||
|
s->version_ack = 0;
|
||||||
s->flags = 0;
|
s->flags = 0;
|
||||||
slave_seen(s);
|
slave_seen(s);
|
||||||
s->next = *root;
|
s->next = *root;
|
||||||
@@ -923,11 +862,8 @@ diffready(krb5_context context, slave *s)
|
|||||||
* Don't send any diffs until slave has sent an I_HAVE telling us the
|
* Don't send any diffs until slave has sent an I_HAVE telling us the
|
||||||
* initial version number!
|
* initial version number!
|
||||||
*/
|
*/
|
||||||
if ((s->flags & SLAVE_F_READY) == 0) {
|
if ((s->flags & SLAVE_F_READY) == 0)
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "not sending diffs to not-ready slave %s", s->name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (s->flags & SLAVE_F_DEAD) {
|
if (s->flags & SLAVE_F_DEAD) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -936,11 +872,8 @@ diffready(krb5_context context, slave *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write any remainder of previous write, if we can. */
|
/* Write any remainder of previous write, if we can. */
|
||||||
if (send_tail(context, s) != 0 && have_tail(s)) {
|
if (send_tail(context, s) != 0)
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "not sending diffs to busy slave %s", s->name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -948,6 +881,10 @@ diffready(krb5_context context, slave *s)
|
|||||||
static int
|
static int
|
||||||
nodiffs(krb5_context context, slave *s, uint32_t current_version)
|
nodiffs(krb5_context context, slave *s, uint32_t current_version)
|
||||||
{
|
{
|
||||||
|
krb5_storage *sp;
|
||||||
|
krb5_data data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (s->version < current_version)
|
if (s->version < current_version)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -960,20 +897,6 @@ nodiffs(krb5_context context, slave *s, uint32_t current_version)
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "slave %s version %ld already sent", s->name,
|
krb5_warnx(context, "slave %s version %ld already sent", s->name,
|
||||||
(long)s->version);
|
(long)s->version);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
send_you_have_last_version(krb5_context context, slave *s)
|
|
||||||
{
|
|
||||||
krb5_storage *sp;
|
|
||||||
krb5_data data;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "slave %s version %ld is latest", s->name,
|
|
||||||
(long)s->version);
|
|
||||||
|
|
||||||
sp = krb5_storage_emem();
|
sp = krb5_storage_emem();
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
krb5_errx(context, IPROPD_RESTART, "krb5_storage_from_mem");
|
krb5_errx(context, IPROPD_RESTART, "krb5_storage_from_mem");
|
||||||
@@ -986,17 +909,19 @@ send_you_have_last_version(krb5_context context, slave *s)
|
|||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = mk_priv_tail(context, s, &data);
|
ret = mk_priv_tail(context, s, &data);
|
||||||
if (ret)
|
|
||||||
krb5_err(context, IPROPD_RESTART, ret,
|
|
||||||
"sending you have last version");
|
|
||||||
krb5_data_free(&data);
|
krb5_data_free(&data);
|
||||||
}
|
}
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
send_tail(context, s);
|
send_tail(context, s);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock the log and return initial version and timestamp
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
get_first(kadm5_server_context *server_context,
|
get_first(kadm5_server_context *server_context, int log_fd,
|
||||||
uint32_t *initial_verp, uint32_t *initial_timep)
|
uint32_t *initial_verp, uint32_t *initial_timep)
|
||||||
{
|
{
|
||||||
krb5_context context = server_context->context;
|
krb5_context context = server_context->context;
|
||||||
@@ -1006,14 +931,19 @@ get_first(kadm5_server_context *server_context,
|
|||||||
* We don't want to perform tight retry loops on log access errors, so on
|
* We don't want to perform tight retry loops on log access errors, so on
|
||||||
* error mark the slave dead. The slave reconnect after a delay...
|
* error mark the slave dead. The slave reconnect after a delay...
|
||||||
*/
|
*/
|
||||||
|
if (flock(log_fd, LOCK_SH) == -1) {
|
||||||
|
krb5_warn(context, errno, "could not obtain shared lock on log file");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_FIRST,
|
ret = kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_FIRST,
|
||||||
initial_verp, initial_timep);
|
initial_verp, initial_timep);
|
||||||
if (ret == HEIM_ERR_EOF || ret == KADM5_LOG_EMPTY)
|
if (ret == HEIM_ERR_EOF)
|
||||||
ret = kadm5_log_get_version_fd(server_context, -1,
|
ret = kadm5_log_get_version_fd(server_context, log_fd,
|
||||||
LOG_VERSION_UBER, initial_verp,
|
LOG_VERSION_UBER, initial_verp,
|
||||||
initial_timep);
|
initial_timep);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
krb5_warn(context, ret, "could not read initial log entry");
|
krb5_warn(context, ret, "could not read initial log entry");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1024,20 +954,17 @@ get_first(kadm5_server_context *server_context,
|
|||||||
/*-
|
/*-
|
||||||
* Find the left end of the diffs in the log we want to send.
|
* Find the left end of the diffs in the log we want to send.
|
||||||
*
|
*
|
||||||
* - On success, return a positive offset to the first new entry.
|
* - On success, return a positive offset to the first new entry, retaining
|
||||||
* - On error, return a negative offset.
|
* a read lock on the log file.
|
||||||
|
* - On error, return a negative offset, with the lock released.
|
||||||
* - If we simply find no successor entry in the log, return zero
|
* - If we simply find no successor entry in the log, return zero
|
||||||
* with the lock released, which indicates that fallback to send_complete()
|
* with the lock released, which indicates that fallback to send_complete()
|
||||||
* is needed.
|
* is needed.
|
||||||
*
|
|
||||||
* The caller must use kadm5_log_snapshot()/kadm5_log_snapshot_verify() to
|
|
||||||
* ensure that the data read here is consistent because there have been only
|
|
||||||
* append writes and/or there have been no log rotations.
|
|
||||||
*/
|
*/
|
||||||
static off_t
|
static off_t
|
||||||
get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
||||||
uint32_t current_version, uint32_t *initial_verp,
|
int log_fd, uint32_t current_version,
|
||||||
uint32_t *initial_timep)
|
uint32_t *initial_verp, uint32_t *initial_timep)
|
||||||
{
|
{
|
||||||
krb5_context context = server_context->context;
|
krb5_context context = server_context->context;
|
||||||
off_t pos;
|
off_t pos;
|
||||||
@@ -1047,13 +974,17 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
uint32_t ver = s->version;
|
uint32_t ver = s->version;
|
||||||
|
|
||||||
ret = get_first(server_context, initial_verp, initial_timep);
|
/* This acquires a read lock on success */
|
||||||
|
ret = get_first(server_context, log_fd,
|
||||||
|
initial_verp, initial_timep);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* When the slave version is out of range, send the whole database. */
|
/* When the slave version is out of range, send the whole database. */
|
||||||
if (ver == 0 || ver + 1 < *initial_verp || ver > current_version)
|
if (ver == 0 || ver < *initial_verp || ver > current_version) {
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Avoid seeking past the last committed record */
|
/* Avoid seeking past the last committed record */
|
||||||
if (kadm5_log_goto_end(server_context, sp) != 0 ||
|
if (kadm5_log_goto_end(server_context, sp) != 0 ||
|
||||||
@@ -1085,12 +1016,13 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Slow path: seek backwards, entry by entry, from the end.
|
* Drop the lock and try to find the left entry by seeking backward
|
||||||
*
|
* from the end of the end of the log. If we succeed, re-acquire the
|
||||||
* Try to find the left entry by seeking backward from the end of the
|
* lock, update "next_diff", and retry the fast-path.
|
||||||
* end of the log. If we succeed, update "next_diff", and retry the
|
|
||||||
* fast-path.
|
|
||||||
*/
|
*/
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
|
|
||||||
|
/* Slow path: seek backwards, entry by entry, from the end */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
enum kadm_ops op;
|
enum kadm_ops op;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
@@ -1106,7 +1038,7 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't expect to reach the slave's version, unless the log
|
* We don't expect to reach the slave's version, unless the log
|
||||||
* has been rotated.
|
* has been modified after we released the lock.
|
||||||
*/
|
*/
|
||||||
if (ver == s->version) {
|
if (ver == s->version) {
|
||||||
krb5_warnx(context, "iprop log truncated while sending diffs "
|
krb5_warnx(context, "iprop log truncated while sending diffs "
|
||||||
@@ -1128,28 +1060,33 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If we loop then we're hoping to hit the fast path so we can return a
|
* If we loop then we're hoping to hit the fast path so we can return a
|
||||||
* non-zero, positive left offset.
|
* non-zero, positive left offset with the lock held.
|
||||||
*
|
*
|
||||||
* We just updated the fast path pre-conditions, so unless a log
|
* We just updated the fast path pre-conditions, so unless a log
|
||||||
* truncation event happens again, we will hit the fast path.
|
* truncation event happens between the point where we dropped the lock
|
||||||
|
* and the point where we rearcuire it above, we will hit the fast
|
||||||
|
* path.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static off_t
|
static off_t
|
||||||
get_right(krb5_context context, krb5_storage *sp, int lastver, slave *s,
|
get_right(krb5_context context, int log_fd, krb5_storage *sp,
|
||||||
off_t left, uint32_t *verp)
|
int lastver, slave *s, off_t left, uint32_t *verp)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
uint32_t ver = s->version;
|
uint32_t ver = s->version;
|
||||||
off_t right = krb5_storage_seek(sp, left, SEEK_SET);
|
off_t right = krb5_storage_seek(sp, left, SEEK_SET);
|
||||||
|
|
||||||
if (right <= 0)
|
if (right <= 0) {
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* The "lastver" bound should preclude us reaching EOF */
|
/* The "lastver" bound should preclude us reaching EOF */
|
||||||
for (; ret == 0 && i < SEND_DIFFS_MAX_RECORDS && ver < lastver; ++i) {
|
for (; ret == 0 && i < SEND_DIFFS_MAX_RECORDS && ver < lastver; ++i) {
|
||||||
@@ -1164,23 +1101,18 @@ get_right(krb5_context context, krb5_storage *sp, int lastver, slave *s,
|
|||||||
right = krb5_storage_seek(sp, 0, SEEK_CUR);
|
right = krb5_storage_seek(sp, 0, SEEK_CUR);
|
||||||
else
|
else
|
||||||
right = -1;
|
right = -1;
|
||||||
if (right <= 0)
|
if (right <= 0) {
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
*verp = ver;
|
*verp = ver;
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void
|
||||||
* This function _must_ send something to the client unless it's dead, and if
|
send_diffs(kadm5_server_context *server_context, slave *s, int log_fd,
|
||||||
* dead it must mark it so (and so close the connection). It is an error to
|
|
||||||
* return from this function without having done so _unless_ the client is
|
|
||||||
* either dead or not ready.
|
|
||||||
*/
|
|
||||||
static kadm5_ret_t
|
|
||||||
send_diffs(kadm5_server_context *server_context, slave *s,
|
|
||||||
const char *database, uint32_t current_version)
|
const char *database, uint32_t current_version)
|
||||||
{
|
{
|
||||||
struct kadm5_log_snap snap;
|
|
||||||
krb5_context context = server_context->context;
|
krb5_context context = server_context->context;
|
||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
uint32_t initial_version;
|
uint32_t initial_version;
|
||||||
@@ -1190,122 +1122,84 @@ send_diffs(kadm5_server_context *server_context, slave *s,
|
|||||||
off_t right = 0;
|
off_t right = 0;
|
||||||
krb5_ssize_t bytes;
|
krb5_ssize_t bytes;
|
||||||
krb5_data data;
|
krb5_data data;
|
||||||
kadm5_ret_t ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/*
|
if (!diffready(context, s) || nodiffs(context, s, current_version))
|
||||||
* diffready() can send part of an extant buffer, and does nothing if the
|
return;
|
||||||
* client is either dead or not ready.
|
|
||||||
*/
|
|
||||||
if (!diffready(context, s))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* From this point onwards we cannot return without having sent anything */
|
|
||||||
|
|
||||||
if (nodiffs(context, s, current_version)) {
|
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "not sending diffs to up-to-date slave %s (no diffs)", s->name);
|
|
||||||
|
|
||||||
send_you_have_last_version(context, s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "sending diffs to live-seeming slave %s", s->name);
|
krb5_warnx(context, "sending diffs to live-seeming slave %s", s->name);
|
||||||
|
|
||||||
ret = kadm5_log_snapshot(server_context, &snap);
|
sp = krb5_storage_from_fd(log_fd);
|
||||||
if (ret) {
|
|
||||||
/*
|
|
||||||
* Here ret would be KADM5_LOG_CORRUPT. What can we do?
|
|
||||||
*/
|
|
||||||
send_you_have_last_version(context, s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp = krb5_storage_from_fd(server_context->log_context.log_fd);
|
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM,
|
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM,
|
||||||
"send_diffs: out of memory");
|
"send_diffs: out of memory");
|
||||||
|
|
||||||
left = get_left(server_context, s, sp, current_version,
|
left = get_left(server_context, s, sp, log_fd, current_version,
|
||||||
&initial_version, &initial_tstamp);
|
&initial_version, &initial_tstamp);
|
||||||
if (left < 0) {
|
if (left < 0) {
|
||||||
/* Some sort of error; fallback on full prop */
|
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (verbose)
|
slave_dead(context, s);
|
||||||
krb5_warnx(context, "sending full prop to slave %s "
|
return;
|
||||||
"(could not find offset for incremental)", s->name);
|
|
||||||
send_complete(context, s, database, current_version,
|
|
||||||
initial_version, initial_tstamp);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left == 0) {
|
if (left == 0) {
|
||||||
/* Slave's version is not in the log, fall back on send_complete() */
|
/* Slave's version is not in the log, fall back on send_complete() */
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "sending full prop to slave %s "
|
|
||||||
"(their version is too old)", s->name);
|
|
||||||
send_complete(context, s, database, current_version,
|
send_complete(context, s, database, current_version,
|
||||||
initial_version, initial_tstamp);
|
initial_version, initial_tstamp);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
right = get_right(server_context->context, sp, current_version,
|
/* We still hold the read lock, if right > 0 */
|
||||||
|
right = get_right(server_context->context, log_fd, sp, current_version,
|
||||||
s, left, &ver);
|
s, left, &ver);
|
||||||
if (right == left) {
|
if (right == left) {
|
||||||
/* Shouldn't happen */
|
flock(log_fd, LOCK_UN);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (verbose)
|
return;
|
||||||
krb5_warnx(context, "not sending diffs to up-to-date slave %s (weird)", s->name);
|
|
||||||
send_you_have_last_version(context, s);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (right < left) {
|
if (right < left) {
|
||||||
assert(right < 0);
|
assert(right < 0);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
slave_dead(context, s);
|
slave_dead(context, s);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (krb5_storage_seek(sp, left, SEEK_SET) != left) {
|
if (krb5_storage_seek(sp, left, SEEK_SET) != left) {
|
||||||
krb5_warn(context, errno ? errno : EIO, "send_diffs: krb5_storage_seek");
|
ret = errno ? errno : EIO;
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
|
krb5_warn(context, ret, "send_diffs: krb5_storage_seek");
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
slave_dead(context, s);
|
slave_dead(context, s);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_data_alloc(&data, right - left + 4);
|
ret = krb5_data_alloc(&data, right - left + 4);
|
||||||
if (ret)
|
if (ret) {
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
flock(log_fd, LOCK_UN);
|
||||||
|
krb5_warn(context, ret, "send_diffs: krb5_data_alloc");
|
||||||
|
krb5_storage_free(sp);
|
||||||
|
slave_dead(context, s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bytes = krb5_storage_read(sp, (char *)data.data + 4, data.length - 4);
|
bytes = krb5_storage_read(sp, (char *)data.data + 4, data.length - 4);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (bytes != data.length - 4) {
|
if (bytes != data.length - 4)
|
||||||
krb5_warnx(context, "send_diffs: log rotated");
|
krb5_errx(context, IPROPD_RESTART, "locked log truncated???");
|
||||||
return KADM5_LOG_SNAPSHOT_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = kadm5_log_snapshot_verify(server_context, &snap);
|
|
||||||
if (ret) {
|
|
||||||
krb5_data_free(&data);
|
|
||||||
if (ret == KADM5_LOG_SNAPSHOT_INVALID) {
|
|
||||||
krb5_warnx(context, "send_diffs: log rotated");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
sp = krb5_storage_from_data(&data);
|
sp = krb5_storage_from_data(&data);
|
||||||
if (sp == NULL)
|
if (sp == NULL) {
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
ret = krb5_store_uint32(sp, FOR_YOU);
|
ret = krb5_store_uint32(sp, FOR_YOU);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0)
|
||||||
ret = mk_priv_tail(context, s, &data);
|
ret = mk_priv_tail(context, s, &data);
|
||||||
if (ret == ENOMEM)
|
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
|
||||||
}
|
|
||||||
krb5_data_free(&data);
|
krb5_data_free(&data);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* Save the fast-path continuation */
|
/* Save the fast-path continuation */
|
||||||
@@ -1327,10 +1221,10 @@ send_diffs(kadm5_server_context *server_context, slave *s,
|
|||||||
krb5_warn(context, ret, "send_diffs: making or sending "
|
krb5_warn(context, ret, "send_diffs: making or sending "
|
||||||
"KRB-PRIV message");
|
"KRB-PRIV message");
|
||||||
slave_dead(context, s);
|
slave_dead(context, s);
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
slave_seen(s);
|
slave_seen(s);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sensible bound on slave message size */
|
/* Sensible bound on slave message size */
|
||||||
@@ -1405,7 +1299,7 @@ read_msg(krb5_context context, slave *s, krb5_data *out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_msg(kadm5_server_context *server_context, slave *s,
|
process_msg(kadm5_server_context *server_context, slave *s, int log_fd,
|
||||||
const char *database, uint32_t current_version)
|
const char *database, uint32_t current_version)
|
||||||
{
|
{
|
||||||
krb5_context context = server_context->context;
|
krb5_context context = server_context->context;
|
||||||
@@ -1413,7 +1307,6 @@ process_msg(kadm5_server_context *server_context, slave *s,
|
|||||||
krb5_data out;
|
krb5_data out;
|
||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
int tries = 3;
|
|
||||||
|
|
||||||
ret = read_msg(context, s, &out);
|
ret = read_msg(context, s, &out);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -1479,9 +1372,9 @@ process_msg(kadm5_server_context *server_context, slave *s,
|
|||||||
krb5_warnx(context, "slave %s ready for updates from version %u",
|
krb5_warnx(context, "slave %s ready for updates from version %u",
|
||||||
s->name, tmp);
|
s->name, tmp);
|
||||||
}
|
}
|
||||||
do {
|
if ((s->version_ack = tmp) < s->version)
|
||||||
ret = send_diffs(server_context, s, database, current_version);
|
break;
|
||||||
} while (ret == KADM5_LOG_SNAPSHOT_INVALID && tries--);
|
send_diffs(server_context, s, log_fd, database, current_version);
|
||||||
break;
|
break;
|
||||||
case I_AM_HERE :
|
case I_AM_HERE :
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -1597,7 +1490,7 @@ write_stats(krb5_context context, slave *slaves, uint32_t current_version)
|
|||||||
} else
|
} else
|
||||||
rtbl_add_column_entry(tbl, SLAVE_ADDRESS, "<unknown>");
|
rtbl_add_column_entry(tbl, SLAVE_ADDRESS, "<unknown>");
|
||||||
|
|
||||||
snprintf(str, sizeof(str), "%u", (unsigned)slaves->version);
|
snprintf(str, sizeof(str), "%u", (unsigned)slaves->version_ack);
|
||||||
rtbl_add_column_entry(tbl, SLAVE_VERSION, str);
|
rtbl_add_column_entry(tbl, SLAVE_VERSION, str);
|
||||||
|
|
||||||
if (slaves->flags & SLAVE_F_DEAD)
|
if (slaves->flags & SLAVE_F_DEAD)
|
||||||
@@ -1677,14 +1570,14 @@ main(int argc, char **argv)
|
|||||||
void *kadm_handle;
|
void *kadm_handle;
|
||||||
kadm5_server_context *server_context;
|
kadm5_server_context *server_context;
|
||||||
kadm5_config_params conf;
|
kadm5_config_params conf;
|
||||||
krb5_socket_t signal_fd, listen_fds[2];
|
krb5_socket_t signal_fd, listen_fd;
|
||||||
|
int log_fd;
|
||||||
slave *slaves = NULL;
|
slave *slaves = NULL;
|
||||||
uint32_t current_version = 0, old_version = 0;
|
uint32_t current_version = 0, old_version = 0;
|
||||||
krb5_keytab keytab;
|
krb5_keytab keytab;
|
||||||
char **files;
|
char **files;
|
||||||
int aret;
|
int aret;
|
||||||
int optidx = 0;
|
int optidx = 0;
|
||||||
int num_listen_fds = 0;
|
|
||||||
int restarter_fd = -1;
|
int restarter_fd = -1;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
@@ -1782,19 +1675,24 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
server_context = (kadm5_server_context *)kadm_handle;
|
server_context = (kadm5_server_context *)kadm_handle;
|
||||||
|
|
||||||
ret = kadm5_log_init_nolock(server_context);
|
log_fd = open (server_context->log_context.log_file, O_RDONLY, 0);
|
||||||
if (ret)
|
if (log_fd < 0)
|
||||||
krb5_err(context, 1, ret, "Could not open iprop log file");
|
krb5_err (context, 1, errno, "open %s",
|
||||||
|
server_context->log_context.log_file);
|
||||||
|
|
||||||
if (fstat(server_context->log_context.log_fd, &st) == -1)
|
if (fstat(log_fd, &st) == -1)
|
||||||
krb5_err(context, 1, errno, "stat %s",
|
krb5_err(context, 1, errno, "stat %s",
|
||||||
server_context->log_context.log_file);
|
server_context->log_context.log_file);
|
||||||
|
|
||||||
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
if (flock(log_fd, LOCK_SH) == -1)
|
||||||
|
krb5_err(context, 1, errno, "shared flock %s",
|
||||||
|
server_context->log_context.log_file);
|
||||||
|
kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_LAST,
|
||||||
¤t_version, NULL);
|
¤t_version, NULL);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
|
|
||||||
signal_fd = make_signal_socket (context);
|
signal_fd = make_signal_socket (context);
|
||||||
make_listen_sockets(context, port_str, listen_fds, &num_listen_fds);
|
listen_fd = make_listen_socket (context, port_str);
|
||||||
|
|
||||||
krb5_warnx(context, "ipropd-master started at version: %lu",
|
krb5_warnx(context, "ipropd-master started at version: %lu",
|
||||||
(unsigned long)current_version);
|
(unsigned long)current_version);
|
||||||
@@ -1806,17 +1704,13 @@ main(int argc, char **argv)
|
|||||||
slave *p;
|
slave *p;
|
||||||
fd_set readset, writeset;
|
fd_set readset, writeset;
|
||||||
int max_fd = 0;
|
int max_fd = 0;
|
||||||
int nready;
|
|
||||||
int i;
|
|
||||||
struct timeval to = {30, 0};
|
struct timeval to = {30, 0};
|
||||||
uint32_t vers;
|
uint32_t vers;
|
||||||
struct stat st2;
|
struct stat st2;;
|
||||||
|
|
||||||
#ifndef NO_LIMIT_FD_SETSIZE
|
#ifndef NO_LIMIT_FD_SETSIZE
|
||||||
if (signal_fd >= FD_SETSIZE || restarter_fd >= FD_SETSIZE)
|
if (signal_fd >= FD_SETSIZE || listen_fd >= FD_SETSIZE ||
|
||||||
krb5_errx (context, IPROPD_RESTART, "fd too large");
|
restarter_fd >= FD_SETSIZE)
|
||||||
for (i = 0; i < num_listen_fds; i++)
|
|
||||||
if (listen_fds[i] >= FD_SETSIZE)
|
|
||||||
krb5_errx (context, IPROPD_RESTART, "fd too large");
|
krb5_errx (context, IPROPD_RESTART, "fd too large");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1824,10 +1718,8 @@ main(int argc, char **argv)
|
|||||||
FD_ZERO(&writeset);
|
FD_ZERO(&writeset);
|
||||||
FD_SET(signal_fd, &readset);
|
FD_SET(signal_fd, &readset);
|
||||||
max_fd = max(max_fd, signal_fd);
|
max_fd = max(max_fd, signal_fd);
|
||||||
for (i = 0; i < num_listen_fds; i++) {
|
FD_SET(listen_fd, &readset);
|
||||||
FD_SET(listen_fds[i], &readset);
|
max_fd = max(max_fd, listen_fd);
|
||||||
max_fd = max(max_fd, listen_fds[i]);
|
|
||||||
}
|
|
||||||
if (restarter_fd > -1) {
|
if (restarter_fd > -1) {
|
||||||
FD_SET(restarter_fd, &readset);
|
FD_SET(restarter_fd, &readset);
|
||||||
max_fd = max(max_fd, restarter_fd);
|
max_fd = max(max_fd, restarter_fd);
|
||||||
@@ -1849,7 +1741,6 @@ main(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
krb5_err (context, IPROPD_RESTART, errno, "select");
|
krb5_err (context, IPROPD_RESTART, errno, "select");
|
||||||
}
|
}
|
||||||
nready = ret;
|
|
||||||
|
|
||||||
if (stat(server_context->log_context.log_file, &st2) == -1) {
|
if (stat(server_context->log_context.log_file, &st2) == -1) {
|
||||||
krb5_warn(context, errno, "could not stat log file by path");
|
krb5_warn(context, errno, "could not stat log file by path");
|
||||||
@@ -1857,24 +1748,36 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (st2.st_dev != st.st_dev || st2.st_ino != st.st_ino) {
|
if (st2.st_dev != st.st_dev || st2.st_ino != st.st_ino) {
|
||||||
kadm5_log_end(server_context);
|
(void) close(log_fd);
|
||||||
|
|
||||||
ret = kadm5_log_init_nolock(server_context);
|
log_fd = open(server_context->log_context.log_file, O_RDONLY, 0);
|
||||||
if (ret)
|
if (log_fd < 0)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ret,
|
krb5_err(context, IPROPD_RESTART_SLOW, errno, "open %s",
|
||||||
"Could not re-open iprop log file");
|
server_context->log_context.log_file);
|
||||||
|
|
||||||
if (fstat(server_context->log_context.log_fd, &st) == -1)
|
if (fstat(log_fd, &st) == -1)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, errno, "stat %s",
|
krb5_err(context, IPROPD_RESTART_SLOW, errno, "stat %s",
|
||||||
server_context->log_context.log_file);
|
server_context->log_context.log_file);
|
||||||
|
|
||||||
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
if (flock(log_fd, LOCK_SH) == -1)
|
||||||
|
krb5_err(context, IPROPD_RESTART, errno, "shared flock %s",
|
||||||
|
server_context->log_context.log_file);
|
||||||
|
kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_LAST,
|
||||||
¤t_version, NULL);
|
¤t_version, NULL);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nready == 0) {
|
if (ret == 0) {
|
||||||
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
/* Recover from failed transactions */
|
||||||
|
if (kadm5_log_init_nb(server_context) == 0)
|
||||||
|
kadm5_log_end(server_context);
|
||||||
|
|
||||||
|
if (flock(log_fd, LOCK_SH) == -1)
|
||||||
|
krb5_err(context, IPROPD_RESTART, errno,
|
||||||
|
"could not lock log file");
|
||||||
|
kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_LAST,
|
||||||
¤t_version, NULL);
|
¤t_version, NULL);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
|
|
||||||
if (current_version > old_version) {
|
if (current_version > old_version) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -1883,25 +1786,21 @@ main(int argc, char **argv)
|
|||||||
(unsigned long)old_version,
|
(unsigned long)old_version,
|
||||||
(unsigned long)current_version);
|
(unsigned long)current_version);
|
||||||
for (p = slaves; p != NULL; p = p->next) {
|
for (p = slaves; p != NULL; p = p->next) {
|
||||||
int tries = 3;
|
|
||||||
|
|
||||||
if (p->flags & SLAVE_F_DEAD)
|
if (p->flags & SLAVE_F_DEAD)
|
||||||
continue;
|
continue;
|
||||||
do {
|
send_diffs(server_context, p, log_fd, database,
|
||||||
ret = send_diffs(server_context, p, database,
|
|
||||||
current_version);
|
current_version);
|
||||||
} while (ret == KADM5_LOG_SNAPSHOT_INVALID && tries--);
|
|
||||||
}
|
}
|
||||||
old_version = current_version;
|
old_version = current_version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nready && restarter_fd > -1 && FD_ISSET(restarter_fd, &readset)) {
|
if (ret && FD_ISSET(restarter_fd, &readset)) {
|
||||||
exit_flag = SIGTERM;
|
exit_flag = SIGTERM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nready && FD_ISSET(signal_fd, &readset)) {
|
if (ret && FD_ISSET(signal_fd, &readset)) {
|
||||||
#ifndef NO_UNIX_SOCKETS
|
#ifndef NO_UNIX_SOCKETS
|
||||||
struct sockaddr_un peer_addr;
|
struct sockaddr_un peer_addr;
|
||||||
#else
|
#else
|
||||||
@@ -1914,11 +1813,15 @@ main(int argc, char **argv)
|
|||||||
krb5_warn (context, errno, "recvfrom");
|
krb5_warn (context, errno, "recvfrom");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
--nready;
|
--ret;
|
||||||
assert(nready >= 0);
|
assert(ret >= 0);
|
||||||
old_version = current_version;
|
old_version = current_version;
|
||||||
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
if (flock(log_fd, LOCK_SH) == -1)
|
||||||
|
krb5_err(context, IPROPD_RESTART, errno, "shared flock %s",
|
||||||
|
server_context->log_context.log_file);
|
||||||
|
kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_LAST,
|
||||||
¤t_version, NULL);
|
¤t_version, NULL);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
if (current_version != old_version) {
|
if (current_version != old_version) {
|
||||||
/*
|
/*
|
||||||
* If current_version < old_version then the log got
|
* If current_version < old_version then the log got
|
||||||
@@ -1938,14 +1841,10 @@ main(int argc, char **argv)
|
|||||||
(unsigned long)old_version,
|
(unsigned long)old_version,
|
||||||
(unsigned long)current_version);
|
(unsigned long)current_version);
|
||||||
for (p = slaves; p != NULL; p = p->next) {
|
for (p = slaves; p != NULL; p = p->next) {
|
||||||
int tries = 3;
|
|
||||||
|
|
||||||
if (p->flags & SLAVE_F_DEAD)
|
if (p->flags & SLAVE_F_DEAD)
|
||||||
continue;
|
continue;
|
||||||
do {
|
send_diffs(server_context, p, log_fd, database,
|
||||||
ret = send_diffs(server_context, p, database,
|
|
||||||
current_version);
|
current_version);
|
||||||
} while (ret == EAGAIN && tries--);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -1960,39 +1859,31 @@ main(int argc, char **argv)
|
|||||||
FD_ISSET(p->fd, &writeset) &&
|
FD_ISSET(p->fd, &writeset) &&
|
||||||
((have_tail(p) && send_tail(context, p) == 0) ||
|
((have_tail(p) && send_tail(context, p) == 0) ||
|
||||||
(!have_tail(p) && more_diffs(p)))) {
|
(!have_tail(p) && more_diffs(p)))) {
|
||||||
int tries = 3;
|
send_diffs(server_context, p, log_fd, database,
|
||||||
|
|
||||||
do {
|
|
||||||
ret = send_diffs(server_context, p, database,
|
|
||||||
current_version);
|
current_version);
|
||||||
} while (ret == KADM5_LOG_SNAPSHOT_INVALID && tries--);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(p = slaves; p != NULL; p = p->next) {
|
for(p = slaves; p != NULL; p = p->next) {
|
||||||
if (p->flags & SLAVE_F_DEAD)
|
if (p->flags & SLAVE_F_DEAD)
|
||||||
continue;
|
continue;
|
||||||
if (nready && FD_ISSET(p->fd, &readset)) {
|
if (ret && FD_ISSET(p->fd, &readset)) {
|
||||||
--nready;
|
--ret;
|
||||||
assert(nready >= 0);
|
assert(ret >= 0);
|
||||||
ret = process_msg(server_context, p, database,
|
ret = process_msg(server_context, p, log_fd, database,
|
||||||
current_version);
|
current_version);
|
||||||
if (ret && ret != EWOULDBLOCK) {
|
if (ret && ret != EWOULDBLOCK)
|
||||||
krb5_warn(context, ret, "process_msg()");
|
|
||||||
slave_dead(context, p);
|
slave_dead(context, p);
|
||||||
}
|
|
||||||
} else if (slave_gone_p (p))
|
} else if (slave_gone_p (p))
|
||||||
slave_dead(context, p);
|
slave_dead(context, p);
|
||||||
else if (slave_missing_p (p))
|
else if (slave_missing_p (p))
|
||||||
send_are_you_there (context, p);
|
send_are_you_there (context, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; nready && i < num_listen_fds; i++) {
|
if (ret && FD_ISSET(listen_fd, &readset)) {
|
||||||
if (FD_ISSET(listen_fds[i], &readset)) {
|
add_slave (context, keytab, &slaves, listen_fd);
|
||||||
add_slave(context, keytab, &slaves, listen_fds[i]);
|
--ret;
|
||||||
--nready;
|
assert(ret >= 0);
|
||||||
assert(nready >= 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
write_stats(context, slaves, current_version);
|
write_stats(context, slaves, current_version);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,14 +124,16 @@ connect_to_master (krb5_context context, const char *master,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_creds(krb5_context context, krb5_ccache *cache)
|
get_creds(krb5_context context, krb5_ccache *cache, const char *serverhost)
|
||||||
{
|
{
|
||||||
krb5_keytab keytab;
|
krb5_keytab keytab;
|
||||||
krb5_principal client;
|
krb5_principal client;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_get_init_creds_opt *init_opts;
|
krb5_get_init_creds_opt *init_opts;
|
||||||
krb5_creds creds;
|
krb5_creds creds;
|
||||||
|
char *server;
|
||||||
char keytab_buf[256];
|
char keytab_buf[256];
|
||||||
|
int aret;
|
||||||
|
|
||||||
if (no_keytab_flag) {
|
if (no_keytab_flag) {
|
||||||
/* We're using an externally refreshed ccache */
|
/* We're using an externally refreshed ccache */
|
||||||
@@ -174,8 +176,13 @@ get_creds(krb5_context context, krb5_ccache *cache)
|
|||||||
ret = krb5_get_init_creds_opt_alloc(context, &init_opts);
|
ret = krb5_get_init_creds_opt_alloc(context, &init_opts);
|
||||||
if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
|
if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
|
||||||
|
|
||||||
|
aret = asprintf (&server, "%s/%s", IPROP_NAME, serverhost);
|
||||||
|
if (aret == -1 || server == NULL)
|
||||||
|
krb5_errx (context, 1, "malloc: no memory");
|
||||||
|
|
||||||
ret = krb5_get_init_creds_keytab(context, &creds, client, keytab,
|
ret = krb5_get_init_creds_keytab(context, &creds, client, keytab,
|
||||||
0, NULL, init_opts);
|
0, server, init_opts);
|
||||||
|
free (server);
|
||||||
krb5_get_init_creds_opt_free(context, init_opts);
|
krb5_get_init_creds_opt_free(context, init_opts);
|
||||||
if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");
|
if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");
|
||||||
|
|
||||||
@@ -348,6 +355,11 @@ receive_loop(krb5_context context,
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "receiving diffs");
|
krb5_warnx(context, "receiving diffs");
|
||||||
|
|
||||||
|
ret = kadm5_log_exclusivelock(server_context);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, IPROPD_RESTART, ret,
|
||||||
|
"Failed to lock iprop log for writes");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Seek to the first entry in the message from the master that is
|
* Seek to the first entry in the message from the master that is
|
||||||
* past the current version of the local database.
|
* past the current version of the local database.
|
||||||
@@ -465,6 +477,9 @@ receive(krb5_context context,
|
|||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ret, "db->close");
|
krb5_err(context, IPROPD_RESTART_SLOW, ret, "db->close");
|
||||||
|
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
kadm5_log_signal_master(server_context);
|
kadm5_log_signal_master(server_context);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "signaled master for hierarchical iprop");
|
krb5_warnx(context, "signaled master for hierarchical iprop");
|
||||||
@@ -516,6 +531,9 @@ reinit_log(krb5_context context,
|
|||||||
ret = kadm5_log_reinit(server_context, vno);
|
ret = kadm5_log_reinit(server_context, vno);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ret, "kadm5_log_reinit");
|
krb5_err(context, IPROPD_RESTART_SLOW, ret, "kadm5_log_reinit");
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -535,6 +553,10 @@ receive_everything(krb5_context context, int fd,
|
|||||||
|
|
||||||
krb5_warnx(context, "receive complete database");
|
krb5_warnx(context, "receive complete database");
|
||||||
|
|
||||||
|
ret = kadm5_log_exclusivelock(server_context);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, IPROPD_RESTART, ret,
|
||||||
|
"Failed to lock iprop log for writes");
|
||||||
if (server_context->db->hdb_method_name) {
|
if (server_context->db->hdb_method_name) {
|
||||||
ret = asprintf(&dbname, "%.*s:%s-NEW",
|
ret = asprintf(&dbname, "%.*s:%s-NEW",
|
||||||
(int) strlen(server_context->db->hdb_method_name) - 1,
|
(int) strlen(server_context->db->hdb_method_name) - 1,
|
||||||
@@ -878,12 +900,15 @@ main(int argc, char **argv)
|
|||||||
ret = kadm5_log_init(server_context);
|
ret = kadm5_log_init(server_context);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, 1, ret, "kadm5_log_init");
|
krb5_err(context, 1, ret, "kadm5_log_init");
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
|
|
||||||
ret = server_context->db->hdb_close(context, server_context->db);
|
ret = server_context->db->hdb_close(context, server_context->db);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, 1, ret, "db->close");
|
krb5_err(context, 1, ret, "db->close");
|
||||||
|
|
||||||
get_creds(context, &ccache);
|
get_creds(context, &ccache, master);
|
||||||
|
|
||||||
ret = krb5_sname_to_principal (context, master, IPROP_NAME,
|
ret = krb5_sname_to_principal (context, master, IPROP_NAME,
|
||||||
KRB5_NT_SRV_HST, &server);
|
KRB5_NT_SRV_HST, &server);
|
||||||
@@ -949,7 +974,7 @@ main(int argc, char **argv)
|
|||||||
krb5_auth_con_free(context, auth_context);
|
krb5_auth_con_free(context, auth_context);
|
||||||
auth_context = NULL;
|
auth_context = NULL;
|
||||||
}
|
}
|
||||||
get_creds(context, &ccache);
|
get_creds(context, &ccache, master);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "authenticating to master");
|
krb5_warnx(context, "authenticating to master");
|
||||||
ret = krb5_sendauth (context, &auth_context, &master_fd,
|
ret = krb5_sendauth (context, &auth_context, &master_fd,
|
||||||
@@ -1066,6 +1091,9 @@ main(int argc, char **argv)
|
|||||||
krb5_err(context, IPROPD_RESTART, ret, "kadm5_log_init while "
|
krb5_err(context, IPROPD_RESTART, ret, "kadm5_log_init while "
|
||||||
"handling a message from the master");
|
"handling a message from the master");
|
||||||
}
|
}
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
|
|
||||||
ret = server_context->db->hdb_close (context, server_context->db);
|
ret = server_context->db->hdb_close (context, server_context->db);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -1097,6 +1125,7 @@ main(int argc, char **argv)
|
|||||||
krb5_warnx(context, "master sent us a full dump");
|
krb5_warnx(context, "master sent us a full dump");
|
||||||
ret = receive_everything(context, master_fd, server_context,
|
ret = receive_everything(context, master_fd, server_context,
|
||||||
auth_context);
|
auth_context);
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = ihave(context, auth_context, master_fd,
|
ret = ihave(context, auth_context, master_fd,
|
||||||
server_context->log_context.version);
|
server_context->log_context.version);
|
||||||
@@ -1105,6 +1134,8 @@ main(int argc, char **argv)
|
|||||||
connected = FALSE;
|
connected = FALSE;
|
||||||
else
|
else
|
||||||
is_up_to_date(context, status_file, server_context);
|
is_up_to_date(context, status_file, server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
kadm5_log_signal_master(server_context);
|
kadm5_log_signal_master(server_context);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "signaled master for hierarchical iprop");
|
krb5_warnx(context, "signaled master for hierarchical iprop");
|
||||||
@@ -1121,7 +1152,6 @@ main(int argc, char **argv)
|
|||||||
*
|
*
|
||||||
* So we don't ihave() here.
|
* So we don't ihave() here.
|
||||||
*/
|
*/
|
||||||
is_up_to_date(context, status_file, server_context);
|
|
||||||
send_im_here(context, master_fd, auth_context);
|
send_im_here(context, master_fd, auth_context);
|
||||||
break;
|
break;
|
||||||
case YOU_HAVE_LAST_VERSION:
|
case YOU_HAVE_LAST_VERSION:
|
||||||
@@ -1145,7 +1175,7 @@ main(int argc, char **argv)
|
|||||||
slave_status(context, status_file, "disconnected from master");
|
slave_status(context, status_file, "disconnected from master");
|
||||||
retry:
|
retry:
|
||||||
if (connected == FALSE)
|
if (connected == FALSE)
|
||||||
krb5_warnx (context, "disconnected from server");
|
krb5_warnx (context, "disconnected for server");
|
||||||
|
|
||||||
if (exit_flag)
|
if (exit_flag)
|
||||||
krb5_warnx (context, "got an exit signal");
|
krb5_warnx (context, "got an exit signal");
|
||||||
|
|||||||
@@ -73,8 +73,6 @@ error_code OLD_SERVER_HOOK_VERSION, "KADM5 server hook is too old for this versi
|
|||||||
error_code NEW_SERVER_HOOK_VERSION, "KADM5 server hook is too new for this version of Heimdal"
|
error_code NEW_SERVER_HOOK_VERSION, "KADM5 server hook is too new for this version of Heimdal"
|
||||||
error_code READ_ONLY, "Database is read-only; try primary server"
|
error_code READ_ONLY, "Database is read-only; try primary server"
|
||||||
error_code PASS_Q_GENERIC, "Unspecified password quality failure"
|
error_code PASS_Q_GENERIC, "Unspecified password quality failure"
|
||||||
error_code LOG_SNAPSHOT_INVALID, "Incremental propagation log rotated; restart operation"
|
|
||||||
error_code LOG_EMPTY, "Incremental propagation log is empty"
|
|
||||||
|
|
||||||
|
|
||||||
# MIT has:
|
# MIT has:
|
||||||
|
|||||||
@@ -86,7 +86,6 @@
|
|||||||
#include <hdb.h>
|
#include <hdb.h>
|
||||||
#include <der.h>
|
#include <der.h>
|
||||||
#include <parse_units.h>
|
#include <parse_units.h>
|
||||||
|
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
#endif /* __KADM5_LOCL_H__ */
|
#endif /* __KADM5_LOCL_H__ */
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ EXPORTS
|
|||||||
kadm5_log_init_sharedlock
|
kadm5_log_init_sharedlock
|
||||||
kadm5_log_next
|
kadm5_log_next
|
||||||
kadm5_log_nop
|
kadm5_log_nop
|
||||||
kadm5_log_snapshot
|
|
||||||
kadm5_log_snapshot_verify
|
|
||||||
kadm5_log_truncate
|
kadm5_log_truncate
|
||||||
kadm5_log_modify
|
kadm5_log_modify
|
||||||
_kadm5_acl_check_permission
|
_kadm5_acl_check_permission
|
||||||
|
|||||||
+15
-175
@@ -174,6 +174,12 @@ RCSID("$Id$");
|
|||||||
* will deadlock with ipropd-slave -- don't do that.
|
* will deadlock with ipropd-slave -- don't do that.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define LOG_HEADER_SZ ((off_t)(sizeof(uint32_t) * 4))
|
||||||
|
#define LOG_TRAILER_SZ ((off_t)(sizeof(uint32_t) * 2))
|
||||||
|
#define LOG_WRAPPER_SZ ((off_t)(LOG_HEADER_SZ + LOG_TRAILER_SZ))
|
||||||
|
#define LOG_UBER_LEN ((off_t)(sizeof(uint64_t) + sizeof(uint32_t) * 2))
|
||||||
|
#define LOG_UBER_SZ ((off_t)(LOG_WRAPPER_SZ + LOG_UBER_LEN))
|
||||||
|
|
||||||
#define LOG_NOPEEK 0
|
#define LOG_NOPEEK 0
|
||||||
#define LOG_DOPEEK 1
|
#define LOG_DOPEEK 1
|
||||||
|
|
||||||
@@ -484,46 +490,12 @@ kadm5_log_get_version_fd(kadm5_server_context *server_context, int fd,
|
|||||||
{
|
{
|
||||||
kadm5_ret_t ret = 0;
|
kadm5_ret_t ret = 0;
|
||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
if (tstamp == NULL)
|
|
||||||
tstamp = &tmp;
|
|
||||||
|
|
||||||
*ver = 0;
|
|
||||||
*tstamp = 0;
|
|
||||||
|
|
||||||
if (fd == -1)
|
|
||||||
fd = server_context->log_context.log_fd;
|
|
||||||
|
|
||||||
sp = krb5_storage_from_fd(fd);
|
|
||||||
if (sp == NULL)
|
|
||||||
return errno ? errno : ENOMEM;
|
|
||||||
|
|
||||||
ret = kadm5_log_get_version_sp(server_context, sp, which, ver, tstamp);
|
|
||||||
krb5_storage_free(sp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_log_get_version_sp(kadm5_server_context *server_context, krb5_storage *sp,
|
|
||||||
int which, uint32_t *ver, uint32_t *tstamp)
|
|
||||||
{
|
|
||||||
struct kadm5_log_snap snap;
|
|
||||||
kadm5_ret_t ret = 0;
|
|
||||||
enum kadm_ops op = kadm_get;
|
enum kadm_ops op = kadm_get;
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
/*
|
if (fd == -1)
|
||||||
* If we're operating lock-less-ly then get a snapshot of the log so we can
|
return 0; /* /dev/null */
|
||||||
* validate that what we read here is correct once we're done reading it.
|
|
||||||
*/
|
|
||||||
memset(&snap, 0, sizeof(snap));
|
|
||||||
if (server_context->log_context.lock_mode == LOCK_UN) {
|
|
||||||
ret = kadm5_log_snapshot(server_context, &snap);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tstamp == NULL)
|
if (tstamp == NULL)
|
||||||
tstamp = &tmp;
|
tstamp = &tmp;
|
||||||
@@ -531,6 +503,10 @@ kadm5_log_get_version_sp(kadm5_server_context *server_context, krb5_storage *sp,
|
|||||||
*ver = 0;
|
*ver = 0;
|
||||||
*tstamp = 0;
|
*tstamp = 0;
|
||||||
|
|
||||||
|
sp = krb5_storage_from_fd(fd);
|
||||||
|
if (sp == NULL)
|
||||||
|
return errno ? errno : ENOMEM;
|
||||||
|
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case LOG_VERSION_LAST:
|
case LOG_VERSION_LAST:
|
||||||
ret = kadm5_log_goto_end(server_context, sp);
|
ret = kadm5_log_goto_end(server_context, sp);
|
||||||
@@ -555,92 +531,10 @@ kadm5_log_get_version_sp(kadm5_server_context *server_context, krb5_storage *sp,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0 && server_context->log_context.lock_mode == LOCK_UN)
|
krb5_storage_free(sp);
|
||||||
/* Validate the snapshot when operating lock-less-ly */
|
|
||||||
return kadm5_log_snapshot_verify(server_context, &snap);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* For lock-less reading of the log first get a snapshot, then read, then
|
|
||||||
* verify the snapshot before using the data read. If snapshot verification
|
|
||||||
* fails, start over.
|
|
||||||
*
|
|
||||||
* This will be used in ipropd-master and iprop-log to avoid needing a lock on
|
|
||||||
* the iprop log. For example, when a client says I_HAVE $ver then the server
|
|
||||||
* gets a snapshot, finds the offset to $ver and the offset to the end of the
|
|
||||||
* log, reads all that into memory, then the server veerifies the snapshot, and
|
|
||||||
* finally it sends the data to client, but if the snapshot verification fails
|
|
||||||
* then the server starts over the process of finding the offset to $ver.
|
|
||||||
*
|
|
||||||
* The way this works is that as long as the log is not rotated and truncated,
|
|
||||||
* then we can expect the header of the first record after the uber-record to
|
|
||||||
* remain the same.
|
|
||||||
*/
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_log_snapshot(kadm5_server_context *server_context,
|
|
||||||
struct kadm5_log_snap *snap)
|
|
||||||
{
|
|
||||||
ssize_t bytes;
|
|
||||||
|
|
||||||
assert(sizeof(snap->buf) < CHAR_MAX);
|
|
||||||
snap->bytes = 0;
|
|
||||||
|
|
||||||
bytes = pread(server_context->log_context.log_fd,
|
|
||||||
snap->buf, sizeof(snap->buf), 0);
|
|
||||||
if (bytes < 0)
|
|
||||||
return errno;
|
|
||||||
if (bytes < LOG_UBER_SZ)
|
|
||||||
return KADM5_LOG_CORRUPT;
|
|
||||||
if (bytes < sizeof(snap->buf))
|
|
||||||
bytes = LOG_UBER_SZ;
|
|
||||||
|
|
||||||
snap->bytes = bytes;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* kadm5_log_snapshot_verify() checks that the iprop log has not been rotated
|
|
||||||
* since the given `snap` snapshot. Returns -1 if the log has been rotated.
|
|
||||||
*/
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_log_snapshot_verify(kadm5_server_context *server_context,
|
|
||||||
struct kadm5_log_snap *snap)
|
|
||||||
{
|
|
||||||
struct kadm5_log_snap v;
|
|
||||||
kadm5_ret_t ret;
|
|
||||||
|
|
||||||
assert(sizeof(snap->buf) < CHAR_MAX);
|
|
||||||
if (snap->bytes < LOG_UBER_SZ)
|
|
||||||
return KADM5_LOG_SNAPSHOT_INVALID;
|
|
||||||
|
|
||||||
ret = kadm5_log_snapshot(server_context, &v);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (v.bytes < LOG_UBER_SZ)
|
|
||||||
return KADM5_LOG_CORRUPT;
|
|
||||||
|
|
||||||
/* The two snapshots are equal -> no log rotation, no log change at all */
|
|
||||||
if (snap->bytes == v.bytes && memcmp(snap->buf, v.buf, v.bytes) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Both snapshots capture the first record's header past the uber record?
|
|
||||||
* Check that that first record's header is the same for both.
|
|
||||||
*/
|
|
||||||
if (snap->bytes == v.bytes && v.bytes == sizeof(v.buf) &&
|
|
||||||
memcmp(snap->buf + LOG_UBER_SZ, v.buf + LOG_UBER_SZ,
|
|
||||||
LOG_HEADER_SZ) == 0)
|
|
||||||
return 0; /* No log rotation, but the log did change */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Log rotated, or we don't have any log entries but the uber record
|
|
||||||
* changed.
|
|
||||||
*/
|
|
||||||
return KADM5_LOG_SNAPSHOT_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the version of the last confirmed entry in the log */
|
/* Get the version of the last confirmed entry in the log */
|
||||||
kadm5_ret_t
|
kadm5_ret_t
|
||||||
kadm5_log_get_version(kadm5_server_context *server_context, uint32_t *ver)
|
kadm5_log_get_version(kadm5_server_context *server_context, uint32_t *ver)
|
||||||
@@ -2239,7 +2133,7 @@ kadm5_log_goto_first(kadm5_server_context *server_context, krb5_storage *sp)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (op == kadm_nop && len == LOG_UBER_LEN && seek_next(sp) == -1)
|
if (op == kadm_nop && len == LOG_UBER_LEN && seek_next(sp) == -1)
|
||||||
return KADM5_LOG_EMPTY;
|
return KADM5_LOG_CORRUPT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2609,13 +2503,6 @@ load_entries(kadm5_server_context *context, krb5_data *p,
|
|||||||
/*
|
/*
|
||||||
* Truncate the log, retaining at most `keep' entries and at most `maxbytes'.
|
* Truncate the log, retaining at most `keep' entries and at most `maxbytes'.
|
||||||
* If `maxbytes' is zero, keep at most the default log size limit.
|
* If `maxbytes' is zero, keep at most the default log size limit.
|
||||||
*
|
|
||||||
* I.e., rotate the log, except we don't rename a new log into place.
|
|
||||||
*
|
|
||||||
* Ensures that the log will be smaller than prior to truncation. This is
|
|
||||||
* important as it ensures that the log snapshot approach used by ipropd-master
|
|
||||||
* to read the log lock-less-ly will work. See also kadm5_log_snapshot() and
|
|
||||||
* kadm5_log_snapshot_verify().
|
|
||||||
*/
|
*/
|
||||||
kadm5_ret_t
|
kadm5_ret_t
|
||||||
kadm5_log_truncate(kadm5_server_context *context, size_t keep, size_t maxbytes)
|
kadm5_log_truncate(kadm5_server_context *context, size_t keep, size_t maxbytes)
|
||||||
@@ -2627,10 +2514,7 @@ kadm5_log_truncate(kadm5_server_context *context, size_t keep, size_t maxbytes)
|
|||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
uint64_t sz;
|
uint64_t sz;
|
||||||
off_t off, fsz;
|
off_t off;
|
||||||
|
|
||||||
if ((fsz = lseek(context->log_context.log_fd, 0, SEEK_END)) < 0)
|
|
||||||
return errno;
|
|
||||||
|
|
||||||
if (maxbytes == 0)
|
if (maxbytes == 0)
|
||||||
maxbytes = get_max_log_size(context->context);
|
maxbytes = get_max_log_size(context->context);
|
||||||
@@ -2665,50 +2549,6 @@ kadm5_log_truncate(kadm5_server_context *context, size_t keep, size_t maxbytes)
|
|||||||
return EOVERFLOW; /* caller should ask for fewer entries */
|
return EOVERFLOW; /* caller should ask for fewer entries */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure that the iprop log will be smaller, or defer truncation */
|
|
||||||
if (sz >= fsz) {
|
|
||||||
uint32_t skip;
|
|
||||||
|
|
||||||
krb5_data_free(&entries);
|
|
||||||
|
|
||||||
if (first > last)
|
|
||||||
first = 1;
|
|
||||||
|
|
||||||
skip = (last - first) / 2;
|
|
||||||
|
|
||||||
if (skip < 2) {
|
|
||||||
/*
|
|
||||||
* There must be an entry that is just large enough, or larger,
|
|
||||||
* that it alone causes the log to exceed the log size
|
|
||||||
* limit.
|
|
||||||
*/
|
|
||||||
krb5_warnx(context->context,
|
|
||||||
"Unable to truncate log due to very large record; "
|
|
||||||
"deferring truncation");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
first += (last - first) / 2;
|
|
||||||
ret = load_entries(context, &entries, last - first, maxbytes, &first, &last);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
sz = LOG_UBER_SZ + entries.length;
|
|
||||||
off = (off_t)sz;
|
|
||||||
if (off < 0 || off != sz || sz < entries.length) {
|
|
||||||
krb5_data_free(&entries);
|
|
||||||
return EOVERFLOW; /* caller should ask for fewer entries */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sz >= fsz) {
|
|
||||||
/* Should never happen! */
|
|
||||||
krb5_data_free(&entries);
|
|
||||||
krb5_warnx(context->context,
|
|
||||||
"Unable to truncate log due to very large record; "
|
|
||||||
"deferring truncation");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Truncate to zero size and seek to zero offset */
|
/* Truncate to zero size and seek to zero offset */
|
||||||
if (ftruncate(context->log_context.log_fd, 0) < 0 ||
|
if (ftruncate(context->log_context.log_fd, 0) < 0 ||
|
||||||
lseek(context->log_context.log_fd, 0, SEEK_SET) < 0) {
|
lseek(context->log_context.log_fd, 0, SEEK_SET) < 0) {
|
||||||
|
|||||||
@@ -87,8 +87,6 @@ HEIMDAL_KAMD5_SERVER_1.0 {
|
|||||||
kadm5_log_init_sharedlock;
|
kadm5_log_init_sharedlock;
|
||||||
kadm5_log_next;
|
kadm5_log_next;
|
||||||
kadm5_log_nop;
|
kadm5_log_nop;
|
||||||
kadm5_log_snapshot;
|
|
||||||
kadm5_log_snapshot_verify;
|
|
||||||
kadm5_log_truncate;
|
kadm5_log_truncate;
|
||||||
kadm5_log_modify;
|
kadm5_log_modify;
|
||||||
_kadm5_acl_check_permission;
|
_kadm5_acl_check_permission;
|
||||||
|
|||||||
+28
-31
@@ -704,30 +704,25 @@ change_password_loop (krb5_context context,
|
|||||||
* do the SOCKS4a I/O.
|
* do the SOCKS4a I/O.
|
||||||
*/
|
*/
|
||||||
while (!_krb5_socks4a_connected(socks4a)) {
|
while (!_krb5_socks4a_connected(socks4a)) {
|
||||||
struct pollfd pfd;
|
fd_set readfds, writefds;
|
||||||
int nready;
|
int nready;
|
||||||
|
|
||||||
pfd.fd = sock;
|
FD_ZERO(&readfds);
|
||||||
pfd.events = 0;
|
FD_ZERO(&writefds);
|
||||||
pfd.revents = 0;
|
|
||||||
|
|
||||||
if (_krb5_socks4a_reading(socks4a))
|
if (_krb5_socks4a_reading(socks4a))
|
||||||
pfd.events |= POLLIN;
|
FD_SET(sock, &readfds);
|
||||||
if (_krb5_socks4a_writing(socks4a))
|
if (_krb5_socks4a_writing(socks4a))
|
||||||
pfd.events |= POLLOUT;
|
FD_SET(sock, &writefds);
|
||||||
|
nready = select(sock + 1, &readfds, &writefds,
|
||||||
nready = poll(&pfd, 1, -1); /* blocking */
|
/*exceptfds*/NULL, /*timeout*/NULL);
|
||||||
if (nready < 0) {
|
if (nready == -1) {
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
ret = errno;
|
ret = errno;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nready == 0) {
|
if (nready <= 0) {
|
||||||
ret = EIO; /* timeout should be impossible */
|
ret = EIO; /* timeout should be impossible */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = _krb5_socks4a_io(socks4a);
|
ret = _krb5_socks4a_io(socks4a);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
@@ -738,6 +733,9 @@ change_password_loop (krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; !done && i < 5; ++i) {
|
for (i = 0; !done && i < 5; ++i) {
|
||||||
|
fd_set fdset;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
if (!replied) {
|
if (!replied) {
|
||||||
replied = 0;
|
replied = 0;
|
||||||
|
|
||||||
@@ -755,28 +753,27 @@ change_password_loop (krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pollfd pfd;
|
#ifndef NO_LIMIT_FD_SETSIZE
|
||||||
int timeout_ms;
|
if (sock >= FD_SETSIZE) {
|
||||||
timeout_ms = (1 + (1 << i)) * 1000;
|
ret = ERANGE;
|
||||||
|
krb5_set_error_message(context, ret,
|
||||||
pfd.fd = sock;
|
"fd %d too large", sock);
|
||||||
pfd.events = POLLIN;
|
|
||||||
pfd.revents = 0;
|
|
||||||
|
|
||||||
ret = poll(&pfd, 1, timeout_ms);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
rk_closesocket (sock);
|
rk_closesocket (sock);
|
||||||
ret = errno;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == 0) {
|
FD_ZERO(&fdset);
|
||||||
ret = KRB5_KDC_UNREACH;
|
FD_SET(sock, &fdset);
|
||||||
continue;
|
tv.tv_usec = 0;
|
||||||
|
tv.tv_sec = 1 + (1 << i);
|
||||||
|
|
||||||
|
ret = select (sock + 1, &fdset, NULL, NULL, &tv);
|
||||||
|
if (rk_IS_SOCKET_ERROR(ret) && rk_SOCK_ERRNO != EINTR) {
|
||||||
|
rk_closesocket(sock);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
if (pfd.revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL)) {
|
if (ret == 1) {
|
||||||
ret = (*proc->process_rep) (context,
|
ret = (*proc->process_rep) (context,
|
||||||
auth_context,
|
auth_context,
|
||||||
is_stream,
|
is_stream,
|
||||||
|
|||||||
+4
-4
@@ -489,7 +489,7 @@ init_context_from_config_file(krb5_context context)
|
|||||||
|
|
||||||
tmp = secure_getenv("KRB5_TRACE");
|
tmp = secure_getenv("KRB5_TRACE");
|
||||||
if (tmp)
|
if (tmp)
|
||||||
heim_add_trace_dest(context->hcontext, "libkrb5", tmp);
|
heim_add_debug_dest(context->hcontext, "libkrb5", tmp);
|
||||||
s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL);
|
s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL);
|
||||||
if (s) {
|
if (s) {
|
||||||
char **p;
|
char **p;
|
||||||
@@ -1108,15 +1108,15 @@ krb5_kerberos_enctypes(krb5_context context)
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const krb5_enctype weak[] = {
|
static const krb5_enctype weak[] = {
|
||||||
ETYPE_AES256_CTS_HMAC_SHA384_192,
|
|
||||||
ETYPE_AES128_CTS_HMAC_SHA256_128,
|
|
||||||
ETYPE_AES256_CTS_HMAC_SHA1_96,
|
ETYPE_AES256_CTS_HMAC_SHA1_96,
|
||||||
ETYPE_AES128_CTS_HMAC_SHA1_96,
|
ETYPE_AES128_CTS_HMAC_SHA1_96,
|
||||||
|
ETYPE_AES256_CTS_HMAC_SHA384_192,
|
||||||
|
ETYPE_AES128_CTS_HMAC_SHA256_128,
|
||||||
ETYPE_ARCFOUR_HMAC_MD5,
|
ETYPE_ARCFOUR_HMAC_MD5,
|
||||||
ETYPE_NULL
|
ETYPE_NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
if (krb5_enctype_valid(context, ETYPE_ARCFOUR_HMAC_MD5) == 0)
|
if (krb5_enctype_valid(context, ETYPE_ARCFOUR_HMAC_MD5))
|
||||||
return weak;
|
return weak;
|
||||||
|
|
||||||
return strong;
|
return strong;
|
||||||
|
|||||||
@@ -608,12 +608,8 @@ krb5_create_checksum(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arcfour_checksum_p(ct, crypto)) {
|
if (arcfour_checksum_p(ct, crypto)) {
|
||||||
#ifdef HEIM_ARCFOUR
|
|
||||||
keyusage = usage;
|
keyusage = usage;
|
||||||
_krb5_usage2arcfour(context, &keyusage);
|
_krb5_usage2arcfour(context, &keyusage);
|
||||||
#else
|
|
||||||
return KRB5_PROG_SUMTYPE_NOSUPP;
|
|
||||||
#endif /* HEIM_ARCFOUR */
|
|
||||||
} else
|
} else
|
||||||
keyusage = CHECKSUM_USAGE(usage);
|
keyusage = CHECKSUM_USAGE(usage);
|
||||||
|
|
||||||
@@ -742,12 +738,8 @@ krb5_verify_checksum(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arcfour_checksum_p(ct, crypto)) {
|
if (arcfour_checksum_p(ct, crypto)) {
|
||||||
#ifdef HEIM_ARCFOUR
|
|
||||||
keyusage = usage;
|
keyusage = usage;
|
||||||
_krb5_usage2arcfour(context, &keyusage);
|
_krb5_usage2arcfour(context, &keyusage);
|
||||||
#else
|
|
||||||
return KRB5_PROG_SUMTYPE_NOSUPP;
|
|
||||||
#endif /* HEIM_ARCFOUR */
|
|
||||||
} else
|
} else
|
||||||
keyusage = CHECKSUM_USAGE(usage);
|
keyusage = CHECKSUM_USAGE(usage);
|
||||||
|
|
||||||
@@ -2075,12 +2067,8 @@ krb5_create_checksum_iov(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arcfour_checksum_p(ct, crypto)) {
|
if (arcfour_checksum_p(ct, crypto)) {
|
||||||
#ifdef HEIM_ARCFOUR
|
|
||||||
keyusage = usage;
|
keyusage = usage;
|
||||||
_krb5_usage2arcfour(context, &keyusage);
|
_krb5_usage2arcfour(context, &keyusage);
|
||||||
#else
|
|
||||||
return KRB5_PROG_SUMTYPE_NOSUPP;
|
|
||||||
#endif /* HEIM_ARCFOUR */
|
|
||||||
} else
|
} else
|
||||||
keyusage = CHECKSUM_USAGE(usage);
|
keyusage = CHECKSUM_USAGE(usage);
|
||||||
|
|
||||||
@@ -2146,12 +2134,8 @@ krb5_verify_checksum_iov(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arcfour_checksum_p(ct, crypto)) {
|
if (arcfour_checksum_p(ct, crypto)) {
|
||||||
#ifdef HEIM_ARCFOUR
|
|
||||||
keyusage = usage;
|
keyusage = usage;
|
||||||
_krb5_usage2arcfour(context, &keyusage);
|
_krb5_usage2arcfour(context, &keyusage);
|
||||||
#else
|
|
||||||
return KRB5_PROG_SUMTYPE_NOSUPP;
|
|
||||||
#endif /* HEIM_ARCFOUR */
|
|
||||||
} else
|
} else
|
||||||
keyusage = CHECKSUM_USAGE(usage);
|
keyusage = CHECKSUM_USAGE(usage);
|
||||||
|
|
||||||
|
|||||||
@@ -69,17 +69,22 @@ krb5_expand_hostname (krb5_context context,
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0 ||
|
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0 ||
|
||||||
krb5_config_get_bool(context, NULL, "libdefaults", "block_dns", NULL))
|
krb5_config_get_bool(context, NULL, "libdefaults", "block_dns", NULL)) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname: DNS canonicalization disabled or blocked for hostname %s", orig_hostname);
|
||||||
return copy_hostname (context, orig_hostname, new_hostname);
|
return copy_hostname (context, orig_hostname, new_hostname);
|
||||||
|
}
|
||||||
|
|
||||||
memset (&hints, 0, sizeof(hints));
|
memset (&hints, 0, sizeof(hints));
|
||||||
hints.ai_flags = AI_CANONNAME;
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
|
||||||
error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
|
error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
|
||||||
if (error)
|
if (error) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname: getaddrinfo(%s) failed: %s", orig_hostname, gai_strerror(error));
|
||||||
return copy_hostname (context, orig_hostname, new_hostname);
|
return copy_hostname (context, orig_hostname, new_hostname);
|
||||||
|
}
|
||||||
for (a = ai; a != NULL; a = a->ai_next) {
|
for (a = ai; a != NULL; a = a->ai_next) {
|
||||||
if (a->ai_canonname != NULL) {
|
if (a->ai_canonname != NULL) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname: canonical name for %s -> %s", orig_hostname, a->ai_canonname);
|
||||||
*new_hostname = strdup (a->ai_canonname);
|
*new_hostname = strdup (a->ai_canonname);
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
if (*new_hostname == NULL)
|
if (*new_hostname == NULL)
|
||||||
@@ -89,6 +94,7 @@ krb5_expand_hostname (krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname: no canonical name found for %s, falling back to copy_hostname", orig_hostname);
|
||||||
return copy_hostname (context, orig_hostname, new_hostname);
|
return copy_hostname (context, orig_hostname, new_hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,20 +151,25 @@ krb5_expand_hostname_realms (krb5_context context,
|
|||||||
int error;
|
int error;
|
||||||
krb5_error_code ret = 0;
|
krb5_error_code ret = 0;
|
||||||
|
|
||||||
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
|
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: DNS canonicalization disabled for hostname %s", orig_hostname);
|
||||||
return vanilla_hostname (context, orig_hostname, new_hostname,
|
return vanilla_hostname (context, orig_hostname, new_hostname,
|
||||||
realms);
|
realms);
|
||||||
|
}
|
||||||
|
|
||||||
memset (&hints, 0, sizeof(hints));
|
memset (&hints, 0, sizeof(hints));
|
||||||
hints.ai_flags = AI_CANONNAME;
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
|
||||||
error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
|
error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
|
||||||
if (error)
|
if (error) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: getaddrinfo(%s) failed: %s", orig_hostname, gai_strerror(error));
|
||||||
return vanilla_hostname (context, orig_hostname, new_hostname,
|
return vanilla_hostname (context, orig_hostname, new_hostname,
|
||||||
realms);
|
realms);
|
||||||
|
}
|
||||||
|
|
||||||
for (a = ai; a != NULL; a = a->ai_next) {
|
for (a = ai; a != NULL; a = a->ai_next) {
|
||||||
if (a->ai_canonname != NULL) {
|
if (a->ai_canonname != NULL) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: canonical name for %s -> %s", orig_hostname, a->ai_canonname);
|
||||||
ret = copy_hostname (context, a->ai_canonname, new_hostname);
|
ret = copy_hostname (context, a->ai_canonname, new_hostname);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
@@ -168,11 +179,13 @@ krb5_expand_hostname_realms (krb5_context context,
|
|||||||
ret = krb5_get_host_realm (context, *new_hostname, realms);
|
ret = krb5_get_host_realm (context, *new_hostname, realms);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: host %s mapped to realm %s", *new_hostname, realms && *realms ? (*realms)[0] : "<unknown>");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free (*new_hostname);
|
free (*new_hostname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: no canonical name/realm found for %s, falling back to vanilla_hostname", orig_hostname);
|
||||||
return vanilla_hostname (context, orig_hostname, new_hostname, realms);
|
return vanilla_hostname (context, orig_hostname, new_hostname, realms);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1081,6 +1081,7 @@ cred_delete(krb5_context context,
|
|||||||
ret = krb5_storage_to_data(sp, &orig_cred_data);
|
ret = krb5_storage_to_data(sp, &orig_cred_data);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
krb5_storage_free(sp);
|
||||||
|
|
||||||
cred_data_in_file = malloc(orig_cred_data.length);
|
cred_data_in_file = malloc(orig_cred_data.length);
|
||||||
if (cred_data_in_file == NULL)
|
if (cred_data_in_file == NULL)
|
||||||
@@ -1102,7 +1103,6 @@ cred_delete(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
krb5_storage_free(sp);
|
|
||||||
sp = krb5_storage_emem();
|
sp = krb5_storage_emem();
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
+1
-1
@@ -645,7 +645,7 @@ get_cred_kdc(krb5_context context,
|
|||||||
krb5_sendto_ctx stctx;
|
krb5_sendto_ctx stctx;
|
||||||
ret = krb5_sendto_ctx_alloc(context, &stctx);
|
ret = krb5_sendto_ctx_alloc(context, &stctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
return ret;
|
||||||
krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL);
|
krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL);
|
||||||
|
|
||||||
if (kdc_hostname)
|
if (kdc_hostname)
|
||||||
|
|||||||
+114
-2
@@ -217,6 +217,31 @@ krb5_kt_resolve(krb5_context context,
|
|||||||
|
|
||||||
residual = keytab_name(name, &type, &type_len);
|
residual = keytab_name(name, &type, &type_len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Aggressive process-context logging:
|
||||||
|
* Print pid/ppid/uid/gid and the raw name string being resolved
|
||||||
|
* so test captures show which process attempted to resolve which
|
||||||
|
* keytab and with what parsed type/residual.
|
||||||
|
*
|
||||||
|
* We intentionally always emit this via krb5_warnx to make sure it
|
||||||
|
* appears in stderr/journal during tests.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
pid_t pid = getpid();
|
||||||
|
pid_t ppid = getppid();
|
||||||
|
uid_t uid = getuid();
|
||||||
|
gid_t gid = getgid();
|
||||||
|
krb5_warnx(context,
|
||||||
|
"krb5_kt_resolve: pid=%d ppid=%d uid=%d gid=%d resolving name=\"%s\" parsed_type=\"%.*s\" residual=\"%s\"",
|
||||||
|
(int)pid,
|
||||||
|
(int)ppid,
|
||||||
|
(int)uid,
|
||||||
|
(int)gid,
|
||||||
|
name ? name : "<null>",
|
||||||
|
(int)type_len, type ? type : "<null>",
|
||||||
|
residual ? residual : "<null>");
|
||||||
|
}
|
||||||
|
|
||||||
for(i = 0; i < context->num_kt_types; i++) {
|
for(i = 0; i < context->num_kt_types; i++) {
|
||||||
if(strncasecmp(type, context->kt_types[i].prefix, type_len) == 0)
|
if(strncasecmp(type, context->kt_types[i].prefix, type_len) == 0)
|
||||||
break;
|
break;
|
||||||
@@ -251,8 +276,15 @@ static const char *default_ktname(krb5_context context)
|
|||||||
const char *tmp = NULL;
|
const char *tmp = NULL;
|
||||||
|
|
||||||
tmp = secure_getenv("KRB5_KTNAME");
|
tmp = secure_getenv("KRB5_KTNAME");
|
||||||
if(tmp != NULL)
|
if(tmp != NULL) {
|
||||||
|
/* Aggressive logging: record environment override */
|
||||||
|
krb5_warnx(context, "default_ktname: using KRB5_KTNAME from env: \"%s\" (pid=%d)", tmp, (int)getpid());
|
||||||
return tmp;
|
return tmp;
|
||||||
|
}
|
||||||
|
/* Aggressive logging: record context default choice as well */
|
||||||
|
krb5_warnx(context, "default_ktname: using context->default_keytab: \"%s\" (pid=%d)",
|
||||||
|
context->default_keytab ? context->default_keytab : "<null>",
|
||||||
|
(int)getpid());
|
||||||
return context->default_keytab;
|
return context->default_keytab;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,6 +629,13 @@ _krb5_kt_principal_not_found(krb5_context context,
|
|||||||
else
|
else
|
||||||
kvno_str[0] = '\0';
|
kvno_str[0] = '\0';
|
||||||
|
|
||||||
|
/* Provide a concise debug line so tests can see what principal/keytab/enctype failed */
|
||||||
|
krb5_warnx(context, "kt_principal_not_found: principal=%s kvno=%s keytab=%s enctype=%s",
|
||||||
|
princ ? princ : "<unknown>",
|
||||||
|
kvno_str[0] ? kvno_str : "<none>",
|
||||||
|
kt_name ? kt_name : "unknown keytab",
|
||||||
|
enctype_str ? enctype_str : "unknown enctype");
|
||||||
|
|
||||||
krb5_set_error_message(context, ret,
|
krb5_set_error_message(context, ret,
|
||||||
N_("Failed to find %s%s in keytab %s (%s)",
|
N_("Failed to find %s%s in keytab %s (%s)",
|
||||||
"principal, kvno, keytab file, enctype"),
|
"principal, kvno, keytab file, enctype"),
|
||||||
@@ -636,27 +675,81 @@ krb5_kt_get_entry_wrapped(krb5_context context,
|
|||||||
|
|
||||||
entry->vno = 0;
|
entry->vno = 0;
|
||||||
while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
|
while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
|
||||||
|
/* Always-log the entry we're inspecting and what is being requested */
|
||||||
|
{
|
||||||
|
char *entry_unp = NULL;
|
||||||
|
char *want_unp = NULL;
|
||||||
|
|
||||||
|
(void) krb5_unparse_name(context, tmp.principal, &entry_unp);
|
||||||
|
(void) krb5_unparse_name(context, principal, &want_unp);
|
||||||
|
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: inspecting entry=%s vno=%d enctype=%d against requested=%s kvno=%u enctype=%d",
|
||||||
|
entry_unp ? entry_unp : "<unparsed>",
|
||||||
|
tmp.vno,
|
||||||
|
tmp.keyblock.keytype,
|
||||||
|
want_unp ? want_unp : "<unparsed>",
|
||||||
|
(unsigned)kvno,
|
||||||
|
(int)enctype);
|
||||||
|
|
||||||
|
free(entry_unp);
|
||||||
|
free(want_unp);
|
||||||
|
}
|
||||||
|
|
||||||
if (krb5_kt_compare(context, &tmp, principal, 0, enctype)) {
|
if (krb5_kt_compare(context, &tmp, principal, 0, enctype)) {
|
||||||
/* the file keytab might only store the lower 8 bits of
|
/* the file keytab might only store the lower 8 bits of
|
||||||
the kvno, so only compare those bits */
|
the kvno, so only compare those bits */
|
||||||
if (kvno == tmp.vno
|
if (kvno == tmp.vno
|
||||||
|| (tmp.vno < 256 && kvno % 256 == tmp.vno)) {
|
|| (tmp.vno < 256 && kvno % 256 == tmp.vno)) {
|
||||||
|
/* Matched principal and kvno -> return this entry */
|
||||||
|
{
|
||||||
|
char *matched = NULL;
|
||||||
|
(void) krb5_unparse_name(context, tmp.principal, &matched);
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: matched entry=%s vno=%d enctype=%d -- returning",
|
||||||
|
matched ? matched : "<unparsed>",
|
||||||
|
tmp.vno,
|
||||||
|
tmp.keyblock.keytype);
|
||||||
|
free(matched);
|
||||||
|
}
|
||||||
krb5_kt_copy_entry_contents (context, &tmp, entry);
|
krb5_kt_copy_entry_contents (context, &tmp, entry);
|
||||||
krb5_kt_free_entry (context, &tmp);
|
krb5_kt_free_entry (context, &tmp);
|
||||||
krb5_kt_end_seq_get(context, id, &cursor);
|
krb5_kt_end_seq_get(context, id, &cursor);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (kvno == 0 && tmp.vno > entry->vno) {
|
} else if (kvno == 0 && tmp.vno > entry->vno) {
|
||||||
|
/* Matched principal but kvno selection logic prefers a higher vno */
|
||||||
|
{
|
||||||
|
char *matched = NULL;
|
||||||
|
(void) krb5_unparse_name(context, tmp.principal, &matched);
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: matched principal %s but kvno differs (entry.vno=%d tmp.vno=%d); selecting higher vno for now",
|
||||||
|
matched ? matched : "<unparsed>",
|
||||||
|
entry->vno,
|
||||||
|
tmp.vno);
|
||||||
|
free(matched);
|
||||||
|
}
|
||||||
if (entry->vno)
|
if (entry->vno)
|
||||||
krb5_kt_free_entry (context, entry);
|
krb5_kt_free_entry (context, entry);
|
||||||
krb5_kt_copy_entry_contents (context, &tmp, entry);
|
krb5_kt_copy_entry_contents (context, &tmp, entry);
|
||||||
|
} else {
|
||||||
|
/* Matched name but kvno didn't match and we are not in kvno-selection mode; log it. */
|
||||||
|
char *matched = NULL;
|
||||||
|
(void) krb5_unparse_name(context, tmp.principal, &matched);
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: matched principal %s but kvno mismatch (tmp.vno=%d requested_kvno=%u); continuing iteration",
|
||||||
|
matched ? matched : "<unparsed>",
|
||||||
|
tmp.vno,
|
||||||
|
(unsigned)kvno);
|
||||||
|
free(matched);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
krb5_kt_free_entry(context, &tmp);
|
krb5_kt_free_entry(context, &tmp);
|
||||||
}
|
}
|
||||||
krb5_kt_end_seq_get (context, id, &cursor);
|
krb5_kt_end_seq_get (context, id, &cursor);
|
||||||
if (entry->vno == 0)
|
if (entry->vno == 0) {
|
||||||
|
/* No matching kvno was found in the keytab iteration; log and return */
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: no matching entry found -> invoking _krb5_kt_principal_not_found");
|
||||||
return _krb5_kt_principal_not_found(context, KRB5_KT_NOTFOUND,
|
return _krb5_kt_principal_not_found(context, KRB5_KT_NOTFOUND,
|
||||||
id, principal, enctype, kvno);
|
id, principal, enctype, kvno);
|
||||||
|
}
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: returning selected entry vno=%d enctype=%d",
|
||||||
|
entry->vno, entry->keyblock.keytype);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,6 +781,25 @@ krb5_kt_get_entry(krb5_context context,
|
|||||||
krb5_const_principal try_princ;
|
krb5_const_principal try_princ;
|
||||||
krb5_name_canon_iterator name_canon_iter;
|
krb5_name_canon_iterator name_canon_iter;
|
||||||
|
|
||||||
|
/* Debug: record incoming keytab lookup request (always emitted) */
|
||||||
|
{
|
||||||
|
char *want_unp = NULL;
|
||||||
|
char *kt_full = NULL;
|
||||||
|
|
||||||
|
if (principal && krb5_unparse_name(context, principal, &want_unp) != 0)
|
||||||
|
want_unp = NULL;
|
||||||
|
(void) krb5_kt_get_full_name(context, id, &kt_full);
|
||||||
|
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry: requested principal=%s keytab=%s kvno=%u enctype=%d",
|
||||||
|
want_unp ? want_unp : "<null>",
|
||||||
|
kt_full ? kt_full : "<unknown>",
|
||||||
|
(unsigned)kvno,
|
||||||
|
(int)enctype);
|
||||||
|
|
||||||
|
free(want_unp);
|
||||||
|
free(kt_full);
|
||||||
|
}
|
||||||
|
|
||||||
if (!principal)
|
if (!principal)
|
||||||
/* Use `NULL' instead of `principal' to quiet static analizers */
|
/* Use `NULL' instead of `principal' to quiet static analizers */
|
||||||
return krb5_kt_get_entry_wrapped(context, id, NULL, kvno, enctype,
|
return krb5_kt_get_entry_wrapped(context, id, NULL, kvno, enctype,
|
||||||
|
|||||||
+57
-8
@@ -380,14 +380,22 @@ fkt_start_seq_get_int(krb5_context context,
|
|||||||
d->filename, strerror(ret));
|
d->filename, strerror(ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Loud logging: record that we opened the keytab file and process info */
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: opened keytab \"%s\" fd=%d flags=0x%x pid=%d uid=%d",
|
||||||
|
d->filename ? d->filename : "<null>",
|
||||||
|
c->fd,
|
||||||
|
(unsigned)flags,
|
||||||
|
(int)getpid(),
|
||||||
|
(int)getuid());
|
||||||
|
|
||||||
rk_cloexec(c->fd);
|
rk_cloexec(c->fd);
|
||||||
if (exclusive) {
|
|
||||||
ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
|
ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: failed to lock keytab \"%s\": ret=%d", d->filename ? d->filename : "<null>", ret);
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ((flags & O_ACCMODE) == O_RDWR && (flags & O_APPEND))
|
if ((flags & O_ACCMODE) == O_RDWR && (flags & O_APPEND))
|
||||||
stdio_mode = "ab+";
|
stdio_mode = "ab+";
|
||||||
else if ((flags & O_ACCMODE) == O_RDWR)
|
else if ((flags & O_ACCMODE) == O_RDWR)
|
||||||
@@ -396,6 +404,7 @@ fkt_start_seq_get_int(krb5_context context,
|
|||||||
stdio_mode = "wb";
|
stdio_mode = "wb";
|
||||||
c->sp = krb5_storage_stdio_from_fd(c->fd, stdio_mode);
|
c->sp = krb5_storage_stdio_from_fd(c->fd, stdio_mode);
|
||||||
if (c->sp == NULL) {
|
if (c->sp == NULL) {
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: krb5_storage_stdio_from_fd returned NULL for \"%s\"", d->filename ? d->filename : "<null>");
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
return krb5_enomem(context);
|
return krb5_enomem(context);
|
||||||
}
|
}
|
||||||
@@ -405,12 +414,17 @@ fkt_start_seq_get_int(krb5_context context,
|
|||||||
krb5_storage_free(c->sp);
|
krb5_storage_free(c->sp);
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
krb5_clear_error_message(context);
|
krb5_clear_error_message(context);
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: failed reading pvno from \"%s\": ret=%d", d->filename ? d->filename : "<null>", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
/* Log the pvno read */
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: keytab \"%s\" pvno=%d", d->filename ? d->filename : "<null>", (int)pvno);
|
||||||
|
|
||||||
if(pvno != 5) {
|
if(pvno != 5) {
|
||||||
krb5_storage_free(c->sp);
|
krb5_storage_free(c->sp);
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
krb5_clear_error_message (context);
|
krb5_clear_error_message (context);
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: keytab \"%s\" has bad vno (%d)", d->filename ? d->filename : "<null>", (int)pvno);
|
||||||
return KRB5_KEYTAB_BADVNO;
|
return KRB5_KEYTAB_BADVNO;
|
||||||
}
|
}
|
||||||
ret = krb5_ret_int8(c->sp, &tag);
|
ret = krb5_ret_int8(c->sp, &tag);
|
||||||
@@ -418,10 +432,19 @@ fkt_start_seq_get_int(krb5_context context,
|
|||||||
krb5_storage_free(c->sp);
|
krb5_storage_free(c->sp);
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
krb5_clear_error_message(context);
|
krb5_clear_error_message(context);
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: failed reading tag from \"%s\": ret=%d", d->filename ? d->filename : "<null>", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Log the tag/version we read */
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: keytab \"%s\" header tag=%d", d->filename ? d->filename : "<null>", (int)tag);
|
||||||
|
|
||||||
id->version = tag;
|
id->version = tag;
|
||||||
storage_set_flags(context, c->sp, id->version);
|
storage_set_flags(context, c->sp, id->version);
|
||||||
|
|
||||||
|
/* Final confirmation log */
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: keytab \"%s\" opened successfully (fd=%d, version=%d)", d->filename ? d->filename : "<null>", c->fd, (int)id->version);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,26 +475,50 @@ fkt_next_entry_int(krb5_context context,
|
|||||||
pos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
|
pos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
|
||||||
loop:
|
loop:
|
||||||
ret = krb5_ret_int32(cursor->sp, &len);
|
ret = krb5_ret_int32(cursor->sp, &len);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: krb5_ret_int32 returned %d for keytab \"%s\" at pos=%lld", ret, d->filename ? d->filename : "<null>", (long long)pos);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
if(len < 0) {
|
if(len < 0) {
|
||||||
pos = krb5_storage_seek(cursor->sp, -len, SEEK_CUR);
|
pos = krb5_storage_seek(cursor->sp, -len, SEEK_CUR);
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
ret = krb5_kt_ret_principal (context, d, cursor->sp, &entry->principal);
|
ret = krb5_kt_ret_principal (context, d, cursor->sp, &entry->principal);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: krb5_kt_ret_principal failed for keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
ret = krb5_ret_uint32(cursor->sp, &utmp32);
|
ret = krb5_ret_uint32(cursor->sp, &utmp32);
|
||||||
entry->timestamp = utmp32;
|
entry->timestamp = utmp32;
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: failed reading timestamp for keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
ret = krb5_ret_int8(cursor->sp, &tmp8);
|
ret = krb5_ret_int8(cursor->sp, &tmp8);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: failed reading vno (8bit) for keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
entry->vno = tmp8;
|
entry->vno = tmp8;
|
||||||
ret = krb5_kt_ret_keyblock (context, d, cursor->sp, &entry->keyblock);
|
ret = krb5_kt_ret_keyblock (context, d, cursor->sp, &entry->keyblock);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: krb5_kt_ret_keyblock failed for keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Log the entry we just read (principal, vno, enctype, timestamp) */
|
||||||
|
{
|
||||||
|
char *princname = NULL;
|
||||||
|
(void) krb5_unparse_name(context, entry->principal, &princname);
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: read entry principal=%s pos=%lld timestamp=%u vno=%d enctype=%d",
|
||||||
|
princname ? princname : "<unparsed>",
|
||||||
|
(long long)pos,
|
||||||
|
(unsigned)entry->timestamp,
|
||||||
|
entry->vno,
|
||||||
|
entry->keyblock.keytype);
|
||||||
|
free(princname);
|
||||||
|
}
|
||||||
|
|
||||||
/* there might be a 32 bit kvno here
|
/* there might be a 32 bit kvno here
|
||||||
* if it's zero, assume that the 8bit one was right,
|
* if it's zero, assume that the 8bit one was right,
|
||||||
* otherwise trust the new value */
|
* otherwise trust the new value */
|
||||||
@@ -494,8 +541,10 @@ loop:
|
|||||||
if(start) *start = pos;
|
if(start) *start = pos;
|
||||||
if(end) *end = pos + 4 + len;
|
if(end) *end = pos + 4 + len;
|
||||||
out:
|
out:
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: error reading keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
krb5_kt_free_entry(context, entry);
|
krb5_kt_free_entry(context, entry);
|
||||||
|
}
|
||||||
krb5_storage_seek(cursor->sp, pos + 4 + len, SEEK_SET);
|
krb5_storage_seek(cursor->sp, pos + 4 + len, SEEK_SET);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
.Dt KRB5_CONTEXT 3
|
.Dt KRB5_CONTEXT 3
|
||||||
.Os HEIMDAL
|
.Os HEIMDAL
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
.Nm krb5_add_et_list ,
|
||||||
.Nm krb5_add_extra_addresses ,
|
.Nm krb5_add_extra_addresses ,
|
||||||
.Nm krb5_add_ignore_addresses ,
|
.Nm krb5_add_ignore_addresses ,
|
||||||
.Nm krb5_context ,
|
.Nm krb5_context ,
|
||||||
@@ -47,7 +48,7 @@
|
|||||||
.Nm krb5_get_ignore_addresses ,
|
.Nm krb5_get_ignore_addresses ,
|
||||||
.Nm krb5_get_kdc_sec_offset ,
|
.Nm krb5_get_kdc_sec_offset ,
|
||||||
.Nm krb5_get_max_time_skew ,
|
.Nm krb5_get_max_time_skew ,
|
||||||
.Nm krb5_get_use_admin_kdc ,
|
.Nm krb5_get_use_admin_kdc
|
||||||
.Nm krb5_init_context ,
|
.Nm krb5_init_context ,
|
||||||
.Nm krb5_init_ets ,
|
.Nm krb5_init_ets ,
|
||||||
.Nm krb5_prepend_config_files ,
|
.Nm krb5_prepend_config_files ,
|
||||||
@@ -58,7 +59,7 @@
|
|||||||
.Nm krb5_set_fcache_version ,
|
.Nm krb5_set_fcache_version ,
|
||||||
.Nm krb5_set_ignore_addresses ,
|
.Nm krb5_set_ignore_addresses ,
|
||||||
.Nm krb5_set_max_time_skew ,
|
.Nm krb5_set_max_time_skew ,
|
||||||
.Nm krb5_set_use_admin_kdc
|
.Nm krb5_set_use_admin_kdc ,
|
||||||
.Nd create, modify and delete krb5_context structures
|
.Nd create, modify and delete krb5_context structures
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
Kerberos 5 Library (libkrb5, -lkrb5)
|
Kerberos 5 Library (libkrb5, -lkrb5)
|
||||||
@@ -80,6 +81,11 @@ Kerberos 5 Library (libkrb5, -lkrb5)
|
|||||||
.Fa "krb5_context context"
|
.Fa "krb5_context context"
|
||||||
.Fc
|
.Fc
|
||||||
.Ft krb5_error_code
|
.Ft krb5_error_code
|
||||||
|
.Fo krb5_add_et_list
|
||||||
|
.Fa "krb5_context context"
|
||||||
|
.Fa "void (*func)(struct et_list **)"
|
||||||
|
.Fc
|
||||||
|
.Ft krb5_error_code
|
||||||
.Fo krb5_add_extra_addresses
|
.Fo krb5_add_extra_addresses
|
||||||
.Fa "krb5_context context"
|
.Fa "krb5_context context"
|
||||||
.Fa "krb5_addresses *addresses"
|
.Fa "krb5_addresses *addresses"
|
||||||
@@ -198,11 +204,23 @@ or that Kerberos should not be used
|
|||||||
.Bq ENXIO .
|
.Bq ENXIO .
|
||||||
.Pp
|
.Pp
|
||||||
.Fn krb5_init_ets
|
.Fn krb5_init_ets
|
||||||
is retained for ABI compatibility.
|
adds all
|
||||||
It does not perform any action.
|
.Xr com_err 3
|
||||||
Any initialization it used to provide is done by
|
libs to
|
||||||
|
.Fa context .
|
||||||
|
This is done by
|
||||||
.Fn krb5_init_context .
|
.Fn krb5_init_context .
|
||||||
.Pp
|
.Pp
|
||||||
|
.Fn krb5_add_et_list
|
||||||
|
adds a
|
||||||
|
.Xr com_err 3
|
||||||
|
error-code handler
|
||||||
|
.Fa func
|
||||||
|
to the specified
|
||||||
|
.Fa context .
|
||||||
|
The error handler must generated by the the re-rentrant version of the
|
||||||
|
.Xr compile_et 1
|
||||||
|
program.
|
||||||
.Fn krb5_add_extra_addresses
|
.Fn krb5_add_extra_addresses
|
||||||
add a list of addresses that should be added when requesting tickets.
|
add a list of addresses that should be added when requesting tickets.
|
||||||
.Pp
|
.Pp
|
||||||
@@ -284,5 +302,7 @@ and
|
|||||||
get and sets the maximum allowed time skew between client and server.
|
get and sets the maximum allowed time skew between client and server.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr errno 2 ,
|
.Xr errno 2 ,
|
||||||
.Xr krb5.conf 5 ,
|
.Xr krb5 3 ,
|
||||||
|
.Xr krb5_config 3 ,
|
||||||
|
.Xr krb5_context 3 ,
|
||||||
.Xr kerberos 8
|
.Xr kerberos 8
|
||||||
|
|||||||
@@ -91,13 +91,11 @@ cleans the the structure, must be used before trying to pass it in to
|
|||||||
.Fn krb5_verify_init_creds .
|
.Fn krb5_verify_init_creds .
|
||||||
.Pp
|
.Pp
|
||||||
.Fn krb5_verify_init_creds_opt_set_ap_req_nofail
|
.Fn krb5_verify_init_creds_opt_set_ap_req_nofail
|
||||||
controls the behavior if
|
controls controls the behavior if
|
||||||
.Fa ap_req_server
|
.Fa ap_req_server
|
||||||
does not exist in the local keytab or in the KDC's database.
|
doesn't exists in the local keytab or in the KDC's database, if it's
|
||||||
If it is true, those errors will not be ignored.
|
true, the error will be ignored. Note that this use is possible
|
||||||
Errors from AP_REQ verification with a present key, such as an integrity
|
insecure.
|
||||||
check failure, are always returned.
|
|
||||||
Note that ignoring the error is possibly insecure.
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr krb5 3 ,
|
.Xr krb5 3 ,
|
||||||
.Xr krb5_get_init_creds 3 ,
|
.Xr krb5_get_init_creds 3 ,
|
||||||
|
|||||||
@@ -231,6 +231,11 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
.Ed
|
.Ed
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
|
.Xr krb5_cc_gen_new 3 ,
|
||||||
|
.Xr krb5_cc_initialize 3 ,
|
||||||
|
.Xr krb5_cc_resolve 3 ,
|
||||||
|
.Xr krb5_err 3 ,
|
||||||
.Xr krb5_free_principal 3 ,
|
.Xr krb5_free_principal 3 ,
|
||||||
.Xr krb5_init_context 3 ,
|
.Xr krb5_init_context 3 ,
|
||||||
|
.Xr krb5_kt_default 3 ,
|
||||||
.Xr krb5.conf 5
|
.Xr krb5.conf 5
|
||||||
|
|||||||
+3
-9
@@ -1193,7 +1193,6 @@ krcc_get_next(krb5_context context,
|
|||||||
if (krcursor == NULL)
|
if (krcursor == NULL)
|
||||||
return KRB5_CC_END;
|
return KRB5_CC_END;
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (krcursor->currkey >= krcursor->numkeys)
|
if (krcursor->currkey >= krcursor->numkeys)
|
||||||
return KRB5_CC_END;
|
return KRB5_CC_END;
|
||||||
|
|
||||||
@@ -1208,19 +1207,14 @@ krcc_get_next(krb5_context context,
|
|||||||
return KRB5_CC_END;
|
return KRB5_CC_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = keyctl_read_krb5_data(krcursor->keys[krcursor->currkey],
|
ret = keyctl_read_krb5_data(krcursor->keys[krcursor->currkey], &payload);
|
||||||
&payload);
|
|
||||||
krcursor->currkey++;
|
|
||||||
if (ret == KRB5_FCC_NOFILE)
|
|
||||||
continue;
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
_krb5_debug(context, 10, "Error reading key %d: %s\n",
|
_krb5_debug(context, 10, "Error reading key %d: %s\n",
|
||||||
krcursor->keys[krcursor->currkey - 1],
|
krcursor->keys[krcursor->currkey],
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
break;
|
krcursor->currkey++;
|
||||||
}
|
|
||||||
|
|
||||||
sp = krb5_storage_from_data(&payload);
|
sp = krb5_storage_from_data(&payload);
|
||||||
if (sp == NULL) {
|
if (sp == NULL) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user