Compare commits
83 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
58b4b1f06e
|
|||
|
583408b3e3
|
|||
|
f8cc75b9c6
|
|||
|
69e74be224
|
|||
|
f6ec5e5f9a
|
|||
|
049748c182
|
|||
|
85b816b5bc
|
|||
|
b795025613
|
|||
|
4cba7c91d1
|
|||
| 6bb4ff842d | |||
| 5b90bc8285 | |||
| 22e73b6fcb | |||
| ac1c2d05bc | |||
| 37f93f85dd | |||
| 6386d8ff82 | |||
| afc4c486a1 | |||
| 9df6b9e13a | |||
| 13d0215c54 | |||
| 759f9f228b | |||
| 5ac91f2dc9 | |||
| d67a2c36c4 | |||
| 9cf1b20313 | |||
| 97b07c5632 | |||
| 8a0fc8d032 | |||
| 34ab0b7c77 | |||
| 9bb80f4747 | |||
| 5ebe5b4582 | |||
| f609aae209 | |||
| fdeb3e6e4e | |||
| 16a8e31d34 | |||
| cdc82913d5 | |||
| 2194be6c92 | |||
| 2594691dfd | |||
| a735b65b70 | |||
| 1f0f31c954 | |||
| e1ab030717 | |||
| 421c40c73e | |||
| de7aa57362 | |||
| 9a9da70626 | |||
| e3a59b65d3 | |||
| 98d6fcacb4 | |||
| 4f147f5e1b | |||
| ef3860d6c3 | |||
| 20d4e914e3 | |||
| cdd22b6061 | |||
| 73acb1df8e | |||
| abec12ef7f | |||
| 2e3bb95430 | |||
| a66cb84e70 | |||
| e89417f2a1 | |||
| a105e8e117 | |||
| 56b55e7c9b | |||
| e836e36d06 | |||
| 19325d4252 | |||
| 3ff4191ba9 | |||
| 73bab3fea5 | |||
| d47f526f55 | |||
| 6efb8b405e | |||
| 6ce504ad84 | |||
| 378a367c9e | |||
| 6d2d9632da | |||
| c65cd331e4 | |||
| f93aeb3f8f | |||
| dafc36e26c | |||
| b7f4f62dfa | |||
| 31c514e3b2 | |||
| 356b2111ba | |||
| 93bbac45f9 | |||
| e4a885074b | |||
| ffb01963fc | |||
| 8dba1f4810 | |||
| e11f8a8823 | |||
| abd35b246a | |||
| bddc275275 | |||
| 609e36de13 | |||
| 8ec31e4926 | |||
| 0a9f1c3f11 | |||
| 4fe0ad8e2c | |||
| c999e5a33a | |||
| ce85c64b84 | |||
| c76a096a28 | |||
| 8a22366b55 | |||
| 1a7e3c4a5c |
@@ -3,6 +3,7 @@ name: Test Coverage
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- 'master'
|
||||||
- 'coverage-*'
|
- 'coverage-*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -36,6 +37,7 @@ 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,8 +49,7 @@ 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 libedit nor SQLite3 because ETOOSLOW
|
# We don't want to scan-build 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,6 +78,7 @@ 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,6 +5,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'master'
|
||||||
- 'heimdal-7-1-branch'
|
- 'heimdal-7-1-branch'
|
||||||
|
- 'test-ILP32'
|
||||||
paths:
|
paths:
|
||||||
- '!docs/**'
|
- '!docs/**'
|
||||||
- '!**.md'
|
- '!**.md'
|
||||||
@@ -63,6 +64,7 @@ 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
|
||||||
@@ -73,7 +75,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 pkg-config python3
|
sudo apt-get install -y libsqlite3-dev libkeyutils-dev libreadline-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:
|
||||||
@@ -83,6 +85,7 @@ 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
|
||||||
@@ -90,6 +93,7 @@ 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 }}
|
||||||
@@ -107,6 +111,27 @@ 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: |
|
||||||
@@ -147,3 +172,75 @@ 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,6 +62,7 @@ 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: |
|
||||||
@@ -93,6 +94,7 @@ 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 }}
|
||||||
@@ -105,6 +107,27 @@ 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
|
||||||
@@ -112,6 +135,7 @@ 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 libedit nor SQLite3 because ETOOSLOW
|
# We don't want to scan-build 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,6 +90,7 @@ 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,6 +46,7 @@ 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,6 +119,7 @@ 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"
|
||||||
|
|||||||
+3
-26
@@ -64,32 +64,6 @@ 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
|
||||||
@@ -720,3 +694,6 @@ 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-*
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ 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,6 +1,7 @@
|
|||||||
[](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
|
||||||
=======
|
=======
|
||||||
@@ -33,3 +34,4 @@ 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)
|
||||||
|
|||||||
+41
-18
@@ -43,6 +43,9 @@ 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) {
|
||||||
@@ -63,6 +66,14 @@ 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);
|
||||||
@@ -70,40 +81,52 @@ 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(1) {
|
while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
|
||||||
ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
|
if(krb5_principal_compare(context, entry.principal, from_princ)) {
|
||||||
if(ret != 0) {
|
krb5_keytab_entry *tmp;
|
||||||
if(ret != KRB5_CC_END && ret != KRB5_KT_END)
|
|
||||||
krb5_warn(context, ret, "getting entry from keytab");
|
tmp = realloc(entries, (num_entries + 1) * sizeof(*entries));
|
||||||
else
|
if (tmp == NULL) {
|
||||||
ret = 0;
|
krb5_kt_free_entry(context, &entry);
|
||||||
|
ret = krb5_enomem(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(krb5_principal_compare(context, entry.principal, from_princ)) {
|
entries = tmp;
|
||||||
krb5_free_principal(context, entry.principal);
|
krb5_free_principal(context, entry.principal);
|
||||||
entry.principal = to_princ;
|
|
||||||
ret = krb5_kt_add_entry(context, keytab, &entry);
|
|
||||||
if(ret) {
|
|
||||||
entry.principal = NULL;
|
entry.principal = NULL;
|
||||||
|
entries[num_entries++] = entry;
|
||||||
|
} else {
|
||||||
krb5_kt_free_entry(context, &entry);
|
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) {
|
||||||
krb5_warn(context, ret, "adding entry");
|
krb5_warn(context, ret, "adding entry");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (opt->delete_flag) {
|
if (opt->delete_flag) {
|
||||||
entry.principal = from_princ;
|
entries[i].principal = from_princ;
|
||||||
ret = krb5_kt_remove_entry(context, keytab, &entry);
|
ret = krb5_kt_remove_entry(context, keytab, &entries[i]);
|
||||||
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]);
|
||||||
}
|
}
|
||||||
krb5_kt_end_seq_get(context, keytab, &cursor);
|
free(entries);
|
||||||
|
|
||||||
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_roken) $(LIB_vers) $(LIB_heimbase)
|
LDADD = $(LIB_vers) $(LIB_heimbase) $(LIB_roken)
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ 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, [
|
||||||
|
|||||||
+70
-10
@@ -9,20 +9,80 @@ AC_DEFUN([KRB_READLINE],[
|
|||||||
|
|
||||||
dnl readline
|
dnl readline
|
||||||
|
|
||||||
ac_foo=no
|
readline_requested="${with_readline-unset}"
|
||||||
build_editline=no
|
libedit_requested="${with_libedit-unset}"
|
||||||
|
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}"
|
||||||
elif test "$ac_cv_func_readline" = yes; then
|
have_readline=yes
|
||||||
:
|
elif test "$readline_requested" != no; then
|
||||||
else
|
rk_readline_header=no
|
||||||
build_libedit=yes
|
AC_CHECK_HEADERS([readline/readline.h readline.h],
|
||||||
LIB_readline="\$(top_builddir)/lib/libedit/src/libheimedit.la \$(LIB_tgetent)"
|
[rk_readline_header=yes])
|
||||||
|
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
|
||||||
|
have_readline=yes
|
||||||
|
with_readline=yes
|
||||||
|
], [], [$LIB_tgetent])
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(LIBEDIT, test "$build_libedit" = yes)
|
|
||||||
AC_DEFINE(HAVE_READLINE, 1,
|
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,
|
||||||
[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,4 +19,10 @@ 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
|
||||||
])
|
])
|
||||||
|
|||||||
+2
-1
@@ -192,7 +192,6 @@ AC_CHECK_FUNCS([ \
|
|||||||
mkdtemp \
|
mkdtemp \
|
||||||
mkostemp \
|
mkostemp \
|
||||||
on_exit \
|
on_exit \
|
||||||
poll \
|
|
||||||
random \
|
random \
|
||||||
secure_getenv \
|
secure_getenv \
|
||||||
setprogname \
|
setprogname \
|
||||||
@@ -360,6 +359,8 @@ 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
|
||||||
|
|||||||
+16
-22
@@ -196,6 +196,22 @@ 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]),
|
||||||
@@ -382,28 +398,6 @@ 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,9 +13,6 @@ 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,48 +123,6 @@ 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
+27
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770380644,
|
||||||
|
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "ae67888ff7ef9dff69b3cf0cc0fbfbcd3a722abe",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs }: let
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
|
||||||
|
systems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-linux"
|
||||||
|
];
|
||||||
|
|
||||||
|
forAllSystems = f: lib.genAttrs systems (system: let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = [
|
||||||
|
self.overlays.${system}.default
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in f system pkgs);
|
||||||
|
in {
|
||||||
|
devShells = forAllSystems (system: pkgs: {
|
||||||
|
default = pkgs.callPackage ./nix/shell.nix { };
|
||||||
|
});
|
||||||
|
|
||||||
|
packages = forAllSystems (system: pkgs: let
|
||||||
|
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;
|
||||||
|
|
||||||
|
src = pkgs.runCommand "heimdal-src" {} "ln -s ${src} \"$out\"";
|
||||||
|
|
||||||
|
heimdal = pkgs.callPackage ./nix/heimdal/package.nix {
|
||||||
|
inherit src;
|
||||||
|
inherit (pkgs.darwin.apple_sdk.frameworks) CoreFoundation Security SystemConfiguration;
|
||||||
|
autoreconfHook = pkgs.buildPackages.autoreconfHook271;
|
||||||
|
};
|
||||||
|
|
||||||
|
nixosTest = pkgs.testers.runNixOSTest (import ./nix/nixosTest.nix { inherit nixpkgs; });
|
||||||
|
});
|
||||||
|
|
||||||
|
overlays = forAllSystems (system: pkgs: {
|
||||||
|
default = final: prev: {
|
||||||
|
heimdal = self.packages.${system}.heimdal;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
nixosModules = {
|
||||||
|
default = self.nixosModules.heimdal;
|
||||||
|
heimdal = ./nix/module;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
+3
-2
@@ -9,9 +9,11 @@ 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 heim_threads.h crypto-headers.h
|
noinst_HEADERS = heimqueue.h crypto-headers.h
|
||||||
|
|
||||||
EXTRA_DIST = NTMakefile krb5-types.cross config.h.w32
|
EXTRA_DIST = NTMakefile krb5-types.cross config.h.w32
|
||||||
|
|
||||||
@@ -48,7 +50,6 @@ 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 \
|
||||||
|
|||||||
+5
-2
@@ -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
|
test_util_SOURCES = test_util.c util.c random_password.c
|
||||||
|
|
||||||
TESTS = test_util
|
TESTS = test_util
|
||||||
|
|
||||||
@@ -72,7 +72,10 @@ 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 \
|
||||||
|
|||||||
+65
-4
@@ -35,6 +35,11 @@
|
|||||||
#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;
|
||||||
|
|
||||||
@@ -203,22 +208,52 @@ 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;
|
||||||
e = select(max_fd + 1, &read_set, NULL, NULL, NULL);
|
#ifdef HAVE_SYSTEMD
|
||||||
|
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");
|
||||||
else {
|
#endif
|
||||||
|
} 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)
|
||||||
@@ -238,6 +273,31 @@ 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 = "+";
|
||||||
|
|
||||||
@@ -300,6 +360,7 @@ 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");
|
||||||
|
|
||||||
|
|||||||
+18
-119
@@ -32,131 +32,30 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kadmin_locl.h"
|
#include "kadmin_locl.h"
|
||||||
|
#include <base64.h>
|
||||||
|
|
||||||
/* This file defines some a function that generates a random password,
|
#define RANDOM_PASSWORD_BYTES 12
|
||||||
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)
|
||||||
{
|
{
|
||||||
#ifdef OTP_STYLE
|
unsigned char random[RANDOM_PASSWORD_BYTES];
|
||||||
{
|
char *password = NULL;
|
||||||
OtpKey newkey;
|
size_t password_len;
|
||||||
|
|
||||||
krb5_generate_random_block(&newkey, sizeof(newkey));
|
if (len == 0)
|
||||||
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);
|
|
||||||
len = 0;
|
krb5_generate_random_block(random, sizeof(random));
|
||||||
for(i = 0; i < num_classes; i++){
|
if (rk_base64url_encode(random, sizeof(random), &password) < 0 ||
|
||||||
classes[i].str = va_arg(ap, const char*);
|
password == NULL) {
|
||||||
classes[i].len = strlen(classes[i].str);
|
memset_s(random, sizeof(random), 0, sizeof(random));
|
||||||
classes[i].freq = va_arg(ap, int);
|
krb5_abortx(NULL, "Failed to encode random password");
|
||||||
len += classes[i].freq;
|
|
||||||
}
|
}
|
||||||
va_end(ap);
|
|
||||||
*pw = malloc(len + 1);
|
password_len = strlen(password);
|
||||||
if(*pw == NULL) {
|
strlcpy(pw, password, len);
|
||||||
free(classes);
|
memset_s(random, sizeof(random), 0, sizeof(random));
|
||||||
return;
|
memset_s(password, password_len, 0, password_len);
|
||||||
}
|
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
|
|
||||||
|
|||||||
+44
-1
@@ -68,6 +68,49 @@ 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)
|
||||||
@@ -82,9 +125,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)
|
kdc_LDADD = libkdc.la $(LDADD) $(LIB_pidfile) $(CAPNG_LIBS) $(SYSTEMD_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)
|
kdc_CFLAGS = $(CAPNG_CFLAGS) $(SYSTEMD_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,6 +33,10 @@
|
|||||||
|
|
||||||
#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
|
||||||
*/
|
*/
|
||||||
@@ -295,6 +299,69 @@ 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.
|
||||||
@@ -1191,6 +1258,11 @@ 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!");
|
||||||
@@ -1209,6 +1281,11 @@ 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 */
|
||||||
@@ -1250,12 +1327,20 @@ 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]);
|
||||||
@@ -1307,11 +1392,17 @@ 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
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -460,6 +460,7 @@ 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;
|
||||||
@@ -581,7 +582,7 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_verify_ap_req2(r->context, &ac,
|
ret = krb5_verify_ap_req2(r->context, &free_ac,
|
||||||
&ap_req,
|
&ap_req,
|
||||||
armor_server_principal,
|
armor_server_principal,
|
||||||
&r->armor_key->key,
|
&r->armor_key->key,
|
||||||
@@ -593,6 +594,8 @@ 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)
|
||||||
@@ -621,7 +624,6 @@ 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;
|
||||||
@@ -747,8 +749,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 (ac && ac != tgs_ac)
|
if (free_ac)
|
||||||
krb5_auth_con_free(r->context, ac);
|
krb5_auth_con_free(r->context, free_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);
|
||||||
|
|||||||
+28
-1
@@ -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_10,
|
KRB5_PLUGIN_KDC_VERSION_11,
|
||||||
kdc_plugin_deps,
|
kdc_plugin_deps,
|
||||||
kdc_get_instance
|
kdc_get_instance
|
||||||
};
|
};
|
||||||
@@ -239,6 +239,33 @@ _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)
|
||||||
{
|
{
|
||||||
|
|||||||
+12
-1
@@ -95,6 +95,16 @@ 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.
|
||||||
*/
|
*/
|
||||||
@@ -117,7 +127,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_10 10
|
#define KRB5_PLUGIN_KDC_VERSION_11 11
|
||||||
|
|
||||||
typedef struct krb5plugin_kdc_ftable {
|
typedef struct krb5plugin_kdc_ftable {
|
||||||
HEIM_PLUGIN_FTABLE_COMMON_ELEMENTS(krb5_context);
|
HEIM_PLUGIN_FTABLE_COMMON_ELEMENTS(krb5_context);
|
||||||
@@ -125,6 +135,7 @@ 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;
|
||||||
|
|||||||
@@ -228,5 +228,5 @@ There should be a way to specify protocol, port, and address triplets,
|
|||||||
not just addresses and protocol, port tuples.
|
not just addresses and protocol, port tuples.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr kinit 1 ,
|
.Xr kinit 1 ,
|
||||||
.Xr krb5.conf 5,
|
.Xr krb5.conf 5 ,
|
||||||
.Xr getservbyname 3
|
.Xr getservbyname 3
|
||||||
|
|||||||
+16
-10
@@ -37,16 +37,15 @@
|
|||||||
#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)INT32_MAX)
|
#define MAX_TIME ((time_t)INT64_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)INT32_MAX)
|
#define MAX_TIME ((time_t)UINT32_MAX)
|
||||||
#else
|
#else
|
||||||
#define MAX_TIME ((time_t)INT32_MAX)
|
#define MAX_TIME ((time_t)UINT64_MAX)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -536,7 +535,11 @@ 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;
|
||||||
@@ -935,6 +938,9 @@ 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,
|
||||||
@@ -946,7 +952,7 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
|
|||||||
r->cname);
|
r->cname);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (labs(kdc_time - p.patimestamp) > r->context->max_skew) {
|
if (krb5_time_abs(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,
|
||||||
@@ -956,7 +962,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)labs(kdc_time - p.patimestamp),
|
(unsigned)krb5_time_abs(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,
|
||||||
@@ -2263,13 +2269,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 (r->client->flags.require_hwauth &&
|
if (!(pat[n].flags & PA_HARDWARE_AUTH)) {
|
||||||
!(pat[n].flags & PA_HARDWARE_AUTH)) {
|
ret = _kdc_hwauth_policy(r);
|
||||||
|
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);
|
||||||
|
|||||||
+10
-17
@@ -399,7 +399,6 @@ 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) {
|
||||||
@@ -417,9 +416,6 @@ 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) {
|
||||||
@@ -441,12 +437,6 @@ 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;
|
||||||
@@ -468,7 +458,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,12 +889,13 @@ _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;
|
||||||
@@ -938,6 +928,12 @@ _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);
|
||||||
|
|
||||||
@@ -983,9 +979,6 @@ _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");
|
||||||
|
|||||||
+4
-2
@@ -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 || labs(a->ctime - now) > context->max_skew) {
|
if (a->ctime == 0 || krb5_time_abs(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 || labs(a->ctime - now) > context->max_skew) {
|
if (a->ctime == 0 || krb5_time_abs(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,6 +797,8 @@ _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);
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -24,7 +24,10 @@ 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 \
|
||||||
|
|||||||
+91
-1
@@ -41,6 +41,11 @@ 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;
|
||||||
@@ -701,7 +706,58 @@ 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 {
|
||||||
@@ -740,22 +796,48 @@ 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;
|
||||||
|
|
||||||
retx = select(maxfd + 1, &fdset, NULL, NULL, NULL);
|
#ifdef HAVE_SYSTEMD
|
||||||
|
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];
|
||||||
@@ -774,8 +856,16 @@ 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]);
|
||||||
|
|||||||
+4
-2
@@ -1104,7 +1104,8 @@ get_new_tickets(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ticket_life != 0) {
|
if (ticket_life != 0) {
|
||||||
if (labs(cred.times.endtime - cred.times.starttime - ticket_life) > 30) {
|
if (krb5_time_abs(cred.times.endtime - cred.times.starttime,
|
||||||
|
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));
|
||||||
@@ -1112,7 +1113,8 @@ get_new_tickets(krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (renew_life) {
|
if (renew_life) {
|
||||||
if (labs(cred.times.renew_till - cred.times.starttime - renew) > 30) {
|
if (krb5_time_abs(cred.times.renew_till - cred.times.starttime,
|
||||||
|
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,8 +1,5 @@
|
|||||||
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
|
||||||
@@ -21,7 +18,6 @@ SUBDIRS = \
|
|||||||
vers \
|
vers \
|
||||||
$(dir_com_err) \
|
$(dir_com_err) \
|
||||||
base \
|
base \
|
||||||
$(dir_editline) \
|
|
||||||
sl \
|
sl \
|
||||||
wind \
|
wind \
|
||||||
asn1 \
|
asn1 \
|
||||||
|
|||||||
@@ -97,8 +97,10 @@ 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,6 +191,7 @@ 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"
|
||||||
@@ -599,6 +600,8 @@ 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,7 +289,11 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -421,6 +425,8 @@ 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");
|
||||||
|
|||||||
+22
-14
@@ -38,12 +38,26 @@
|
|||||||
#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, \
|
||||||
@@ -1493,9 +1507,7 @@ _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 ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
if (int32_ptr_equal(*i, tdefval->ptr))
|
||||||
(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;
|
||||||
@@ -1567,9 +1579,7 @@ _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 ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
if (int32_ptr_equal(*i, tdefval->ptr))
|
||||||
(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;
|
||||||
@@ -2072,9 +2082,7 @@ _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 ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
if (int32_ptr_equal(*i, tdefval->ptr))
|
||||||
(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;
|
||||||
@@ -2131,9 +2139,7 @@ _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 ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
if (int32_ptr_equal(*i, tdefval->ptr))
|
||||||
(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;
|
||||||
@@ -2483,8 +2489,10 @@ _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)) {
|
||||||
unsigned align = 8 - ((t->offset + sizeof(*elementp)) & 0x7);
|
size_t offset = t->offset + sizeof(*elementp);
|
||||||
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;
|
||||||
|
|||||||
+17
-2
@@ -46,6 +46,21 @@ 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
|
||||||
@@ -55,7 +70,7 @@ static const unsigned ndays[2][12] ={
|
|||||||
time_t
|
time_t
|
||||||
_der_timegm (struct tm *tm)
|
_der_timegm (struct tm *tm)
|
||||||
{
|
{
|
||||||
time_t res = 0;
|
uint64_t res = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -89,7 +104,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 res;
|
return _clamp_time_t(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tm *
|
struct tm *
|
||||||
|
|||||||
+23
-3
@@ -86,6 +86,26 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -94,7 +114,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(name, (*q)->name) == 0)
|
strcmp_du(name, (*q)->name) == 0)
|
||||||
return *q;
|
return *q;
|
||||||
*q = calloc(1, sizeof(**q));
|
*q = calloc(1, sizeof(**q));
|
||||||
if (*q == NULL)
|
if (*q == NULL)
|
||||||
@@ -788,7 +808,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(b->name, name) == 0) {
|
if (strcmp_du(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;
|
||||||
@@ -826,7 +846,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(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) {
|
if(strcmp_du(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) {
|
||||||
*pointer = b;
|
*pointer = b;
|
||||||
return b->u.generic;
|
return b->u.generic;
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-9
@@ -355,11 +355,12 @@ open_file(heim_context context, heim_log_facility *fac, int min, int max,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
heim_error_code
|
static heim_error_code
|
||||||
heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig)
|
addlog_dest(heim_context context, heim_log_facility *f,
|
||||||
|
const char *orig, int default_min, int default_max)
|
||||||
{
|
{
|
||||||
heim_error_code ret = 0;
|
heim_error_code ret = 0;
|
||||||
int min = 0, max = 3, n;
|
int min = default_min, max = default_max, n;
|
||||||
char c;
|
char c;
|
||||||
const char *p = orig;
|
const char *p = orig;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -393,8 +394,6 @@ heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig)
|
|||||||
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,
|
||||||
@@ -445,6 +444,12 @@ heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig)
|
|||||||
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,
|
||||||
@@ -648,9 +653,9 @@ heim_add_warn_dest(heim_context context, const char *program,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
heim_error_code
|
static heim_error_code
|
||||||
heim_add_debug_dest(heim_context context, const char *program,
|
add_debug_dest(heim_context context, const char *program,
|
||||||
const char *log_spec)
|
const char *log_spec, int default_min, int default_max)
|
||||||
{
|
{
|
||||||
heim_log_facility *fac;
|
heim_log_facility *fac;
|
||||||
heim_error_code ret;
|
heim_error_code ret;
|
||||||
@@ -662,12 +667,26 @@ heim_add_debug_dest(heim_context context, const char *program,
|
|||||||
heim_set_debug_dest(context, fac);
|
heim_set_debug_dest(context, fac);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = heim_addlog_dest(context, fac, log_spec);
|
ret = addlog_dest(context, fac, log_spec, default_min, default_max);
|
||||||
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,6 +142,83 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -1365,6 +1442,7 @@ 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,6 +10,7 @@ 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,6 +15,7 @@
|
|||||||
.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
|
||||||
@@ -35,6 +36,11 @@ 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
|
||||||
|
|||||||
+37
-7
@@ -435,11 +435,13 @@ 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, int negotiate)
|
accept_one(gss_name_t service, const char *ccname, const char *localuser,
|
||||||
|
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_name_t client = GSS_C_NO_NAME;
|
||||||
|
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;
|
||||||
@@ -495,8 +497,23 @@ accept_one(gss_name_t service, const char *ccname, int negotiate)
|
|||||||
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);
|
|
||||||
(void) gss_delete_sec_context(&min, &ctx, GSS_C_NO_BUFFER);
|
if (localuser) {
|
||||||
|
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
|
||||||
@@ -532,6 +549,12 @@ 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);
|
||||||
|
|
||||||
@@ -585,8 +608,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] [-c count] "
|
fprintf(f, " gss-token -r [-Nln] [-C ccache] [-L localuser] "
|
||||||
"[service@host]\n");
|
"[-c count] [service@host]\n");
|
||||||
exit(ecode);
|
exit(ecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -606,12 +629,14 @@ 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 },
|
||||||
@@ -662,6 +687,11 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -673,7 +703,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = accept_one(service, ccname, Nflag);
|
ret = accept_one(service, ccname, localuser, 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(NULL, &handle->mechanisms);
|
gss_release_oid_set(minor_status, &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,6 +238,7 @@ 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)
|
||||||
@@ -245,7 +246,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(NULL, &handle->mechanisms);
|
gss_release_oid_set(&tmp_status, &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) != 1) {
|
EVP_Cipher(rc4_key, p, p, 8) != 8) {
|
||||||
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) != 1) {
|
EVP_Cipher(rc4_key, SND_SEQ, p, 8) != 8) {
|
||||||
_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) != 1) {
|
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen) != 8 + datalen) {
|
||||||
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) != 1) {
|
EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8) != 8) {
|
||||||
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) != 1) {
|
EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8) != 8) {
|
||||||
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) != 1 ||
|
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 8 ||
|
||||||
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen) != 1) {
|
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen) != datalen) {
|
||||||
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) != 1) {
|
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8) != 8) {
|
||||||
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) != 1) {
|
iov[i].buffer.value, iov[i].buffer.length) != iov[i].buffer.length) {
|
||||||
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) != 1) {
|
padding->buffer.value, padding->buffer.length) != padding->buffer.length) {
|
||||||
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) != 1 /* SND_SEQ */) {
|
EVP_Cipher(rc4_key, p0 + 8, p0 + 8, 8) != 8 /* 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) != 1 /* SND_SEQ */) {
|
EVP_Cipher(rc4_key, snd_seq, p0 + 8, 8) != 8 /* 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) != 1) {
|
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 8) {
|
||||||
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) != 1) {
|
iov[i].buffer.value, iov[i].buffer.length) != iov[i].buffer.length) {
|
||||||
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) != 1) {
|
padding->buffer.value, padding->buffer.length) != padding->buffer.length) {
|
||||||
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,11 +100,12 @@ 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(NULL, src_name);
|
_gsskrb5_release_name(&tmp_status, src_name);
|
||||||
if (targ_name)
|
if (targ_name)
|
||||||
_gsskrb5_release_name(NULL, targ_name);
|
_gsskrb5_release_name(&tmp_status, targ_name);
|
||||||
|
}
|
||||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ 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)
|
||||||
@@ -49,7 +50,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(NULL, mech_types);
|
gss_release_oid_set(&tmp_status, mech_types);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ 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;
|
||||||
@@ -71,7 +72,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_names_for_mech (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret != GSS_S_COMPLETE)
|
if (ret != GSS_S_COMPLETE)
|
||||||
gss_release_oid_set(NULL, name_types);
|
gss_release_oid_set(&tmp_status, name_types);
|
||||||
|
|
||||||
return GSS_S_COMPLETE;
|
return GSS_S_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,8 +83,25 @@ 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++) {
|
||||||
putenv(env->elements[i].value);
|
char *var = (char *)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,12 +265,14 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -318,6 +320,9 @@ 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
|
||||||
@@ -360,6 +365,9 @@ 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) {
|
||||||
@@ -510,7 +518,8 @@ got_one:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_gss_mg_log(10, "gss-asc: return %d/%d", (int)major_status, (int)*minor_status);
|
_gss_mg_log(10, "gss-asc: ctx=%p return %d/%d", ctx,
|
||||||
|
(int)major_status, (int)*minor_status);
|
||||||
|
|
||||||
if (ret_flags)
|
if (ret_flags)
|
||||||
*ret_flags = mech_ret_flags;
|
*ret_flags = mech_ret_flags;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ 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;
|
||||||
@@ -68,6 +69,8 @@ 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,6 +28,8 @@
|
|||||||
|
|
||||||
#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,
|
||||||
@@ -44,6 +46,8 @@ _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;
|
||||||
|
|
||||||
@@ -169,6 +173,32 @@ _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.
|
||||||
*
|
*
|
||||||
@@ -230,6 +260,7 @@ 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);
|
||||||
@@ -262,6 +293,9 @@ 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,7 +167,8 @@ 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 "\n"); \
|
_gss_mg_log(1, "can't find symbol gss_" #name \
|
||||||
|
" in %s", lib); \
|
||||||
goto bad; \
|
goto bad; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -334,9 +335,11 @@ _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;
|
||||||
}
|
}
|
||||||
@@ -346,7 +349,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\n", dlerror());
|
_gss_mg_log(1, "dlopen: %s", dlerror());
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ 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 },
|
||||||
@@ -109,16 +111,133 @@ 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");
|
NULL, "from_ccache to_ccache | source_name target_name");
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -157,16 +276,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,
|
||||||
@@ -174,13 +293,25 @@ 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 into %s", argv[1]);
|
"failed to store creds");
|
||||||
|
|
||||||
if (env_flag) {
|
if (env_flag) {
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -204,6 +335,22 @@ 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 delegarated cred but did get one");
|
errx(1, "asked for delegated 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");
|
||||||
|
|
||||||
|
|||||||
@@ -169,12 +169,15 @@ 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 \
|
||||||
@@ -336,6 +339,7 @@ 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 \
|
||||||
|
|||||||
+14
-2
@@ -66,6 +66,18 @@ 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.
|
||||||
@@ -1773,13 +1785,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 (notBefore < 1 || (int64_t)notBefore < 2524608000)
|
if (use_utc_time(notBefore))
|
||||||
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 (notAfter < 1 || (int64_t)notAfter < 2524608000)
|
if (use_utc_time(notAfter))
|
||||||
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;
|
||||||
|
|||||||
+38
-1
@@ -78,6 +78,7 @@ 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;
|
||||||
@@ -635,6 +636,8 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,7 +696,23 @@ hx509_cert_copy_no_private_key(hx509_context context,
|
|||||||
hx509_cert src,
|
hx509_cert src,
|
||||||
heim_error_t *error)
|
heim_error_t *error)
|
||||||
{
|
{
|
||||||
return hx509_cert_init(context, src->data, error);
|
hx509_cert cert;
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -747,6 +766,7 @@ 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;
|
||||||
@@ -769,6 +789,19 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,6 +857,7 @@ 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);
|
||||||
@@ -4057,6 +4091,9 @@ 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) {
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
-----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,6 +47,23 @@ 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
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
+13
-3
@@ -46,14 +46,23 @@ 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.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.defs
|
heim_ipc.stamp: 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_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.defs
|
heim_ipc.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.stamp
|
||||||
|
|
||||||
|
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_reply.h heim_ipc_replyUser.c: heim_ipc_reply.defs
|
heim_ipc_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.stamp
|
||||||
|
|
||||||
|
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
|
||||||
@@ -69,6 +78,7 @@ 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,8 +41,6 @@
|
|||||||
#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,6 +53,17 @@
|
|||||||
#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
|
||||||
|
|||||||
+21
-7
@@ -203,12 +203,10 @@ kadm5_c_dup_context(void *vin, void **out)
|
|||||||
kadm5_client_context *ctx;
|
kadm5_client_context *ctx;
|
||||||
|
|
||||||
*out = NULL;
|
*out = NULL;
|
||||||
ctx = malloc(sizeof(*ctx));
|
ctx = calloc(1, 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;
|
||||||
@@ -226,8 +224,13 @@ 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)
|
||||||
|
ret = krb5_enomem(context);
|
||||||
if (in->keytab && (ctx->keytab = strdup(in->keytab)) == NULL)
|
if (in->keytab && (ctx->keytab = strdup(in->keytab)) == NULL)
|
||||||
ret = krb5_enomem(context);
|
ret = krb5_enomem(context);
|
||||||
|
ctx->prompter = in->prompter;
|
||||||
|
|
||||||
if (in->ccache) {
|
if (in->ccache) {
|
||||||
char *fullname = NULL;
|
char *fullname = NULL;
|
||||||
|
|
||||||
@@ -455,9 +458,19 @@ _kadm5_c_get_cred_cache(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ccache != NULL) {
|
if(ccache != NULL) {
|
||||||
id = ccache;
|
char *fullname = NULL;
|
||||||
|
|
||||||
|
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;
|
||||||
} else {
|
} else {
|
||||||
/* get principal from default cache, ok if this doesn't work */
|
/* get principal from default cache, ok if this doesn't work */
|
||||||
@@ -515,7 +528,7 @@ _kadm5_c_get_cred_cache(krb5_context context,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* get creds via AS request */
|
/* get creds via AS request */
|
||||||
if(id && (id != ccache))
|
if (id)
|
||||||
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);
|
||||||
@@ -708,7 +721,8 @@ kadm5_c_init_with_context(krb5_context 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,
|
||||||
|
|||||||
+282
-173
@@ -86,37 +86,46 @@ 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, const char *port_str)
|
make_listen_socket(krb5_context context, int port)
|
||||||
{
|
{
|
||||||
krb5_socket_t fd;
|
krb5_socket_t fd;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
fd = socket (AF_INET, SOCK_STREAM, 0);
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (rk_IS_BAD_SOCKET(fd))
|
if (rk_IS_BAD_SOCKET(fd))
|
||||||
krb5_err (context, 1, rk_SOCK_ERRNO, "socket AF_INET");
|
krb5_err (context, 1, rk_SOCK_ERRNO, "socket AF_INET");
|
||||||
(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)
|
||||||
@@ -124,15 +133,68 @@ make_listen_socket (krb5_context context, const char *port_str)
|
|||||||
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_in addr;
|
struct sockaddr_storage 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
|
||||||
@@ -376,7 +438,6 @@ 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;
|
||||||
@@ -862,8 +923,11 @@ 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)
|
||||||
@@ -872,8 +936,11 @@ 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)
|
if (send_tail(context, s) != 0 && have_tail(s)) {
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "not sending diffs to busy slave %s", s->name);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -881,10 +948,6 @@ 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;
|
||||||
|
|
||||||
@@ -897,6 +960,20 @@ 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");
|
||||||
@@ -909,19 +986,17 @@ nodiffs(krb5_context context, slave *s, uint32_t current_version)
|
|||||||
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, int log_fd,
|
get_first(kadm5_server_context *server_context,
|
||||||
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;
|
||||||
@@ -931,19 +1006,14 @@ get_first(kadm5_server_context *server_context, int log_fd,
|
|||||||
* 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, log_fd, LOG_VERSION_FIRST,
|
ret = kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_FIRST,
|
||||||
initial_verp, initial_timep);
|
initial_verp, initial_timep);
|
||||||
if (ret == HEIM_ERR_EOF)
|
if (ret == HEIM_ERR_EOF || ret == KADM5_LOG_EMPTY)
|
||||||
ret = kadm5_log_get_version_fd(server_context, log_fd,
|
ret = kadm5_log_get_version_fd(server_context, -1,
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -954,17 +1024,20 @@ get_first(kadm5_server_context *server_context, int log_fd,
|
|||||||
/*-
|
/*-
|
||||||
* 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, retaining
|
* - On success, return a positive offset to the first new entry.
|
||||||
* a read lock on the log file.
|
* - On error, return a negative offset.
|
||||||
* - 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,
|
||||||
int log_fd, uint32_t current_version,
|
uint32_t current_version, uint32_t *initial_verp,
|
||||||
uint32_t *initial_verp, uint32_t *initial_timep)
|
uint32_t *initial_timep)
|
||||||
{
|
{
|
||||||
krb5_context context = server_context->context;
|
krb5_context context = server_context->context;
|
||||||
off_t pos;
|
off_t pos;
|
||||||
@@ -974,17 +1047,13 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
uint32_t ver = s->version;
|
uint32_t ver = s->version;
|
||||||
|
|
||||||
/* This acquires a read lock on success */
|
ret = get_first(server_context, initial_verp, initial_timep);
|
||||||
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 < *initial_verp || ver > current_version) {
|
if (ver == 0 || ver + 1 < *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 ||
|
||||||
@@ -1016,13 +1085,12 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Drop the lock and try to find the left entry by seeking backward
|
* Slow path: seek backwards, entry by entry, from the end.
|
||||||
* from the end of the end of the log. If we succeed, re-acquire the
|
*
|
||||||
* lock, update "next_diff", and retry the fast-path.
|
* Try to find the left entry by seeking backward from the end of the
|
||||||
|
* 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;
|
||||||
@@ -1038,7 +1106,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 modified after we released the lock.
|
* has been rotated.
|
||||||
*/
|
*/
|
||||||
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 "
|
||||||
@@ -1060,33 +1128,28 @@ 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 with the lock held.
|
* non-zero, positive left offset.
|
||||||
*
|
*
|
||||||
* 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 between the point where we dropped the lock
|
* truncation event happens again, we will hit the fast path.
|
||||||
* 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, int log_fd, krb5_storage *sp,
|
get_right(krb5_context context, krb5_storage *sp, int lastver, slave *s,
|
||||||
int lastver, slave *s, off_t left, uint32_t *verp)
|
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) {
|
||||||
@@ -1101,18 +1164,23 @@ get_right(krb5_context context, int log_fd, krb5_storage *sp,
|
|||||||
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
|
/*
|
||||||
send_diffs(kadm5_server_context *server_context, slave *s, int log_fd,
|
* This function _must_ send something to the client unless it's dead, and if
|
||||||
|
* 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;
|
||||||
@@ -1122,84 +1190,122 @@ send_diffs(kadm5_server_context *server_context, slave *s, int log_fd,
|
|||||||
off_t right = 0;
|
off_t right = 0;
|
||||||
krb5_ssize_t bytes;
|
krb5_ssize_t bytes;
|
||||||
krb5_data data;
|
krb5_data data;
|
||||||
int ret = 0;
|
kadm5_ret_t ret = 0;
|
||||||
|
|
||||||
if (!diffready(context, s) || nodiffs(context, s, current_version))
|
/*
|
||||||
return;
|
* diffready() can send part of an extant buffer, and does nothing if the
|
||||||
|
* 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);
|
||||||
|
|
||||||
sp = krb5_storage_from_fd(log_fd);
|
ret = kadm5_log_snapshot(server_context, &snap);
|
||||||
|
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, log_fd, current_version,
|
left = get_left(server_context, s, sp, 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);
|
||||||
slave_dead(context, s);
|
if (verbose)
|
||||||
return;
|
krb5_warnx(context, "sending full prop to slave %s "
|
||||||
|
"(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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We still hold the read lock, if right > 0 */
|
right = get_right(server_context->context, sp, current_version,
|
||||||
right = get_right(server_context->context, log_fd, sp, current_version,
|
|
||||||
s, left, &ver);
|
s, left, &ver);
|
||||||
if (right == left) {
|
if (right == left) {
|
||||||
flock(log_fd, LOCK_UN);
|
/* Shouldn't happen */
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
return;
|
if (verbose)
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (krb5_storage_seek(sp, left, SEEK_SET) != left) {
|
if (krb5_storage_seek(sp, left, SEEK_SET) != left) {
|
||||||
ret = errno ? errno : EIO;
|
krb5_warn(context, errno ? errno : EIO, "send_diffs: krb5_storage_seek");
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_data_alloc(&data, right - left + 4);
|
ret = krb5_data_alloc(&data, right - left + 4);
|
||||||
if (ret) {
|
if (ret)
|
||||||
flock(log_fd, LOCK_UN);
|
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
||||||
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_errx(context, IPROPD_RESTART, "locked log truncated???");
|
krb5_warnx(context, "send_diffs: log rotated");
|
||||||
|
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 */
|
||||||
@@ -1221,10 +1327,10 @@ send_diffs(kadm5_server_context *server_context, slave *s, int log_fd,
|
|||||||
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;
|
return ret;
|
||||||
}
|
}
|
||||||
slave_seen(s);
|
slave_seen(s);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sensible bound on slave message size */
|
/* Sensible bound on slave message size */
|
||||||
@@ -1299,7 +1405,7 @@ read_msg(krb5_context context, slave *s, krb5_data *out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_msg(kadm5_server_context *server_context, slave *s, int log_fd,
|
process_msg(kadm5_server_context *server_context, slave *s,
|
||||||
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;
|
||||||
@@ -1307,6 +1413,7 @@ process_msg(kadm5_server_context *server_context, slave *s, int log_fd,
|
|||||||
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) {
|
||||||
@@ -1372,9 +1479,9 @@ process_msg(kadm5_server_context *server_context, slave *s, int log_fd,
|
|||||||
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);
|
||||||
}
|
}
|
||||||
if ((s->version_ack = tmp) < s->version)
|
do {
|
||||||
break;
|
ret = send_diffs(server_context, s, database, current_version);
|
||||||
send_diffs(server_context, s, log_fd, database, current_version);
|
} while (ret == KADM5_LOG_SNAPSHOT_INVALID && tries--);
|
||||||
break;
|
break;
|
||||||
case I_AM_HERE :
|
case I_AM_HERE :
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -1490,7 +1597,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_ack);
|
snprintf(str, sizeof(str), "%u", (unsigned)slaves->version);
|
||||||
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)
|
||||||
@@ -1570,14 +1677,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_fd;
|
krb5_socket_t signal_fd, listen_fds[2];
|
||||||
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;
|
||||||
|
|
||||||
@@ -1675,24 +1782,19 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
server_context = (kadm5_server_context *)kadm_handle;
|
server_context = (kadm5_server_context *)kadm_handle;
|
||||||
|
|
||||||
log_fd = open (server_context->log_context.log_file, O_RDONLY, 0);
|
ret = kadm5_log_init_nolock(server_context);
|
||||||
if (log_fd < 0)
|
if (ret)
|
||||||
krb5_err (context, 1, errno, "open %s",
|
krb5_err(context, 1, ret, "Could not open iprop log file");
|
||||||
server_context->log_context.log_file);
|
|
||||||
|
|
||||||
if (fstat(log_fd, &st) == -1)
|
if (fstat(server_context->log_context.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);
|
||||||
|
|
||||||
if (flock(log_fd, LOCK_SH) == -1)
|
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
||||||
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);
|
||||||
listen_fd = make_listen_socket (context, port_str);
|
make_listen_sockets(context, port_str, listen_fds, &num_listen_fds);
|
||||||
|
|
||||||
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);
|
||||||
@@ -1704,13 +1806,17 @@ 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 || listen_fd >= FD_SETSIZE ||
|
if (signal_fd >= FD_SETSIZE || restarter_fd >= FD_SETSIZE)
|
||||||
restarter_fd >= FD_SETSIZE)
|
krb5_errx (context, IPROPD_RESTART, "fd too large");
|
||||||
|
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
|
||||||
|
|
||||||
@@ -1718,8 +1824,10 @@ 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);
|
||||||
FD_SET(listen_fd, &readset);
|
for (i = 0; i < num_listen_fds; i++) {
|
||||||
max_fd = max(max_fd, listen_fd);
|
FD_SET(listen_fds[i], &readset);
|
||||||
|
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);
|
||||||
@@ -1741,6 +1849,7 @@ 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");
|
||||||
@@ -1748,36 +1857,24 @@ 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) {
|
||||||
(void) close(log_fd);
|
kadm5_log_end(server_context);
|
||||||
|
|
||||||
log_fd = open(server_context->log_context.log_file, O_RDONLY, 0);
|
ret = kadm5_log_init_nolock(server_context);
|
||||||
if (log_fd < 0)
|
if (ret)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, errno, "open %s",
|
krb5_err(context, IPROPD_RESTART_SLOW, ret,
|
||||||
server_context->log_context.log_file);
|
"Could not re-open iprop log file");
|
||||||
|
|
||||||
if (fstat(log_fd, &st) == -1)
|
if (fstat(server_context->log_context.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);
|
||||||
|
|
||||||
if (flock(log_fd, LOCK_SH) == -1)
|
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
||||||
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 (ret == 0) {
|
if (nready == 0) {
|
||||||
/* Recover from failed transactions */
|
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
||||||
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)
|
||||||
@@ -1786,21 +1883,25 @@ 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;
|
||||||
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--);
|
||||||
}
|
}
|
||||||
old_version = current_version;
|
old_version = current_version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret && FD_ISSET(restarter_fd, &readset)) {
|
if (nready && restarter_fd > -1 && FD_ISSET(restarter_fd, &readset)) {
|
||||||
exit_flag = SIGTERM;
|
exit_flag = SIGTERM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret && FD_ISSET(signal_fd, &readset)) {
|
if (nready && 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
|
||||||
@@ -1813,15 +1914,11 @@ main(int argc, char **argv)
|
|||||||
krb5_warn (context, errno, "recvfrom");
|
krb5_warn (context, errno, "recvfrom");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
--ret;
|
--nready;
|
||||||
assert(ret >= 0);
|
assert(nready >= 0);
|
||||||
old_version = current_version;
|
old_version = current_version;
|
||||||
if (flock(log_fd, LOCK_SH) == -1)
|
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
||||||
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
|
||||||
@@ -1841,10 +1938,14 @@ 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;
|
||||||
send_diffs(server_context, p, log_fd, database,
|
do {
|
||||||
|
ret = send_diffs(server_context, p, database,
|
||||||
current_version);
|
current_version);
|
||||||
|
} while (ret == EAGAIN && tries--);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -1859,31 +1960,39 @@ 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)))) {
|
||||||
send_diffs(server_context, p, log_fd, database,
|
int tries = 3;
|
||||||
|
|
||||||
|
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 (ret && FD_ISSET(p->fd, &readset)) {
|
if (nready && FD_ISSET(p->fd, &readset)) {
|
||||||
--ret;
|
--nready;
|
||||||
assert(ret >= 0);
|
assert(nready >= 0);
|
||||||
ret = process_msg(server_context, p, log_fd, database,
|
ret = process_msg(server_context, p, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret && FD_ISSET(listen_fd, &readset)) {
|
for (i = 0; nready && i < num_listen_fds; i++) {
|
||||||
add_slave (context, keytab, &slaves, listen_fd);
|
if (FD_ISSET(listen_fds[i], &readset)) {
|
||||||
--ret;
|
add_slave(context, keytab, &slaves, listen_fds[i]);
|
||||||
assert(ret >= 0);
|
--nready;
|
||||||
|
assert(nready >= 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
write_stats(context, slaves, current_version);
|
write_stats(context, slaves, current_version);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,16 +124,14 @@ connect_to_master (krb5_context context, const char *master,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_creds(krb5_context context, krb5_ccache *cache, const char *serverhost)
|
get_creds(krb5_context context, krb5_ccache *cache)
|
||||||
{
|
{
|
||||||
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 */
|
||||||
@@ -176,13 +174,8 @@ get_creds(krb5_context context, krb5_ccache *cache, const char *serverhost)
|
|||||||
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, server, init_opts);
|
0, NULL, 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");
|
||||||
|
|
||||||
@@ -355,11 +348,6 @@ 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.
|
||||||
@@ -477,9 +465,6 @@ 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");
|
||||||
@@ -531,9 +516,6 @@ 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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -553,10 +535,6 @@ 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,
|
||||||
@@ -900,15 +878,12 @@ 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, master);
|
get_creds(context, &ccache);
|
||||||
|
|
||||||
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);
|
||||||
@@ -974,7 +949,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, master);
|
get_creds(context, &ccache);
|
||||||
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,
|
||||||
@@ -1091,9 +1066,6 @@ 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)
|
||||||
@@ -1125,7 +1097,6 @@ 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);
|
||||||
@@ -1134,8 +1105,6 @@ 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");
|
||||||
@@ -1152,6 +1121,7 @@ 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:
|
||||||
@@ -1175,7 +1145,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 for server");
|
krb5_warnx (context, "disconnected from server");
|
||||||
|
|
||||||
if (exit_flag)
|
if (exit_flag)
|
||||||
krb5_warnx (context, "got an exit signal");
|
krb5_warnx (context, "got an exit signal");
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ 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,6 +86,7 @@
|
|||||||
#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,6 +85,8 @@ 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
|
||||||
|
|||||||
+174
-14
@@ -174,12 +174,6 @@ 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
|
||||||
|
|
||||||
@@ -490,23 +484,53 @@ 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;
|
||||||
enum kadm_ops op = kadm_get;
|
|
||||||
uint32_t len = 0;
|
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
if (fd == -1)
|
|
||||||
return 0; /* /dev/null */
|
|
||||||
|
|
||||||
if (tstamp == NULL)
|
if (tstamp == NULL)
|
||||||
tstamp = &tmp;
|
tstamp = &tmp;
|
||||||
|
|
||||||
*ver = 0;
|
*ver = 0;
|
||||||
*tstamp = 0;
|
*tstamp = 0;
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
fd = server_context->log_context.log_fd;
|
||||||
|
|
||||||
sp = krb5_storage_from_fd(fd);
|
sp = krb5_storage_from_fd(fd);
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
return errno ? errno : ENOMEM;
|
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;
|
||||||
|
uint32_t len = 0;
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're operating lock-less-ly then get a snapshot of the log so we can
|
||||||
|
* 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)
|
||||||
|
tstamp = &tmp;
|
||||||
|
|
||||||
|
*ver = 0;
|
||||||
|
*tstamp = 0;
|
||||||
|
|
||||||
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);
|
||||||
@@ -531,10 +555,92 @@ kadm5_log_get_version_fd(kadm5_server_context *server_context, int fd,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
krb5_storage_free(sp);
|
if (ret == 0 && server_context->log_context.lock_mode == LOCK_UN)
|
||||||
|
/* 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)
|
||||||
@@ -2133,7 +2239,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_CORRUPT;
|
return KADM5_LOG_EMPTY;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2503,6 +2609,13 @@ 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)
|
||||||
@@ -2514,7 +2627,10 @@ 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;
|
off_t off, fsz;
|
||||||
|
|
||||||
|
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);
|
||||||
@@ -2549,6 +2665,50 @@ 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,6 +87,8 @@ 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;
|
||||||
|
|||||||
+31
-28
@@ -704,25 +704,30 @@ 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)) {
|
||||||
fd_set readfds, writefds;
|
struct pollfd pfd;
|
||||||
int nready;
|
int nready;
|
||||||
|
|
||||||
FD_ZERO(&readfds);
|
pfd.fd = sock;
|
||||||
FD_ZERO(&writefds);
|
pfd.events = 0;
|
||||||
|
pfd.revents = 0;
|
||||||
|
|
||||||
if (_krb5_socks4a_reading(socks4a))
|
if (_krb5_socks4a_reading(socks4a))
|
||||||
FD_SET(sock, &readfds);
|
pfd.events |= POLLIN;
|
||||||
if (_krb5_socks4a_writing(socks4a))
|
if (_krb5_socks4a_writing(socks4a))
|
||||||
FD_SET(sock, &writefds);
|
pfd.events |= POLLOUT;
|
||||||
nready = select(sock + 1, &readfds, &writefds,
|
|
||||||
/*exceptfds*/NULL, /*timeout*/NULL);
|
nready = poll(&pfd, 1, -1); /* blocking */
|
||||||
if (nready == -1) {
|
if (nready < 0) {
|
||||||
|
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;
|
||||||
@@ -733,9 +738,6 @@ 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;
|
||||||
|
|
||||||
@@ -753,27 +755,28 @@ change_password_loop (krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_LIMIT_FD_SETSIZE
|
struct pollfd pfd;
|
||||||
if (sock >= FD_SETSIZE) {
|
int timeout_ms;
|
||||||
ret = ERANGE;
|
timeout_ms = (1 + (1 << i)) * 1000;
|
||||||
krb5_set_error_message(context, ret,
|
|
||||||
"fd %d too large", sock);
|
|
||||||
rk_closesocket (sock);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FD_ZERO(&fdset);
|
pfd.fd = sock;
|
||||||
FD_SET(sock, &fdset);
|
pfd.events = POLLIN;
|
||||||
tv.tv_usec = 0;
|
pfd.revents = 0;
|
||||||
tv.tv_sec = 1 + (1 << i);
|
|
||||||
|
|
||||||
ret = select (sock + 1, &fdset, NULL, NULL, &tv);
|
ret = poll(&pfd, 1, timeout_ms);
|
||||||
if (rk_IS_SOCKET_ERROR(ret) && rk_SOCK_ERRNO != EINTR) {
|
if (ret < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
rk_closesocket(sock);
|
rk_closesocket(sock);
|
||||||
|
ret = errno;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (ret == 1) {
|
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = KRB5_KDC_UNREACH;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pfd.revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL)) {
|
||||||
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_debug_dest(context->hcontext, "libkrb5", tmp);
|
heim_add_trace_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_SHA1_96,
|
|
||||||
ETYPE_AES128_CTS_HMAC_SHA1_96,
|
|
||||||
ETYPE_AES256_CTS_HMAC_SHA384_192,
|
ETYPE_AES256_CTS_HMAC_SHA384_192,
|
||||||
ETYPE_AES128_CTS_HMAC_SHA256_128,
|
ETYPE_AES128_CTS_HMAC_SHA256_128,
|
||||||
|
ETYPE_AES256_CTS_HMAC_SHA1_96,
|
||||||
|
ETYPE_AES128_CTS_HMAC_SHA1_96,
|
||||||
ETYPE_ARCFOUR_HMAC_MD5,
|
ETYPE_ARCFOUR_HMAC_MD5,
|
||||||
ETYPE_NULL
|
ETYPE_NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
if (krb5_enctype_valid(context, ETYPE_ARCFOUR_HMAC_MD5))
|
if (krb5_enctype_valid(context, ETYPE_ARCFOUR_HMAC_MD5) == 0)
|
||||||
return weak;
|
return weak;
|
||||||
|
|
||||||
return strong;
|
return strong;
|
||||||
|
|||||||
@@ -608,8 +608,12 @@ 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);
|
||||||
|
|
||||||
@@ -738,8 +742,12 @@ 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);
|
||||||
|
|
||||||
@@ -2067,8 +2075,12 @@ 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);
|
||||||
|
|
||||||
@@ -2134,8 +2146,12 @@ 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);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1081,7 +1081,6 @@ 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)
|
||||||
@@ -1103,6 +1102,7 @@ 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)
|
||||||
return ret;
|
goto out;
|
||||||
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)
|
||||||
|
|||||||
@@ -381,11 +381,13 @@ fkt_start_seq_get_int(krb5_context context,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
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) {
|
||||||
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)
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
.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 ,
|
||||||
@@ -48,7 +47,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 ,
|
||||||
@@ -59,7 +58,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)
|
||||||
@@ -81,11 +80,6 @@ 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"
|
||||||
@@ -204,23 +198,11 @@ or that Kerberos should not be used
|
|||||||
.Bq ENXIO .
|
.Bq ENXIO .
|
||||||
.Pp
|
.Pp
|
||||||
.Fn krb5_init_ets
|
.Fn krb5_init_ets
|
||||||
adds all
|
is retained for ABI compatibility.
|
||||||
.Xr com_err 3
|
It does not perform any action.
|
||||||
libs to
|
Any initialization it used to provide is done by
|
||||||
.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
|
||||||
@@ -302,7 +284,5 @@ 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 3 ,
|
.Xr krb5.conf 5 ,
|
||||||
.Xr krb5_config 3 ,
|
|
||||||
.Xr krb5_context 3 ,
|
|
||||||
.Xr kerberos 8
|
.Xr kerberos 8
|
||||||
|
|||||||
@@ -91,11 +91,13 @@ 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 controls the behavior if
|
controls the behavior if
|
||||||
.Fa ap_req_server
|
.Fa ap_req_server
|
||||||
doesn't exists in the local keytab or in the KDC's database, if it's
|
does not exist in the local keytab or in the KDC's database.
|
||||||
true, the error will be ignored. Note that this use is possible
|
If it is true, those errors will not be ignored.
|
||||||
insecure.
|
Errors from AP_REQ verification with a present key, such as an integrity
|
||||||
|
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,11 +231,6 @@ 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
|
||||||
|
|||||||
+9
-3
@@ -1193,6 +1193,7 @@ 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;
|
||||||
|
|
||||||
@@ -1207,14 +1208,19 @@ krcc_get_next(krb5_context context,
|
|||||||
return KRB5_CC_END;
|
return KRB5_CC_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = keyctl_read_krb5_data(krcursor->keys[krcursor->currkey], &payload);
|
ret = keyctl_read_krb5_data(krcursor->keys[krcursor->currkey],
|
||||||
|
&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],
|
krcursor->keys[krcursor->currkey - 1],
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
krcursor->currkey++;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
sp = krb5_storage_from_data(&payload);
|
sp = krb5_storage_from_data(&payload);
|
||||||
if (sp == NULL) {
|
if (sp == NULL) {
|
||||||
|
|||||||
+63
-47
@@ -1084,13 +1084,6 @@ submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi)
|
|||||||
continue;
|
continue;
|
||||||
rk_cloexec(fd);
|
rk_cloexec(fd);
|
||||||
|
|
||||||
#ifndef NO_LIMIT_FD_SETSIZE
|
|
||||||
if (fd >= FD_SETSIZE) {
|
|
||||||
_krb5_debug(context, 0, "fd too large for select");
|
|
||||||
rk_closesocket(fd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
socket_set_nonblocking(fd, 1);
|
socket_set_nonblocking(fd, 1);
|
||||||
|
|
||||||
host = heim_alloc(sizeof(*host), "sendto-host", deallocate_host);
|
host = heim_alloc(sizeof(*host), "sendto-host", deallocate_host);
|
||||||
@@ -1162,9 +1155,11 @@ submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi)
|
|||||||
struct wait_ctx {
|
struct wait_ctx {
|
||||||
krb5_context context;
|
krb5_context context;
|
||||||
krb5_sendto_ctx ctx;
|
krb5_sendto_ctx ctx;
|
||||||
fd_set rfds;
|
|
||||||
fd_set wfds;
|
struct pollfd *pfds;
|
||||||
rk_socket_t max_fd;
|
struct host **hosts;
|
||||||
|
nfds_t nfds;
|
||||||
|
|
||||||
int got_reply;
|
int got_reply;
|
||||||
time_t timenow;
|
time_t timenow;
|
||||||
};
|
};
|
||||||
@@ -1175,6 +1170,8 @@ wait_setup(heim_object_t obj, void *iter_ctx, int *stop)
|
|||||||
struct wait_ctx *wait_ctx = iter_ctx;
|
struct wait_ctx *wait_ctx = iter_ctx;
|
||||||
struct host *h = (struct host *)obj;
|
struct host *h = (struct host *)obj;
|
||||||
|
|
||||||
|
short events = 0;
|
||||||
|
|
||||||
if (h->state == CONNECT) {
|
if (h->state == CONNECT) {
|
||||||
if (h->timeout >= wait_ctx->timenow)
|
if (h->timeout >= wait_ctx->timenow)
|
||||||
return;
|
return;
|
||||||
@@ -1199,30 +1196,31 @@ wait_setup(heim_object_t obj, void *iter_ctx, int *stop)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_LIMIT_FD_SETSIZE
|
|
||||||
heim_assert(h->fd < FD_SETSIZE, "fd too large");
|
|
||||||
#endif
|
|
||||||
switch (h->state) {
|
switch (h->state) {
|
||||||
case WAITING_REPLY:
|
case WAITING_REPLY:
|
||||||
FD_SET(h->fd, &wait_ctx->rfds);
|
events |= POLLIN;
|
||||||
break;
|
break;
|
||||||
case CONNECTING:
|
case CONNECTING:
|
||||||
case CONNECTED:
|
case CONNECTED:
|
||||||
FD_SET(h->fd, &wait_ctx->rfds);
|
events |= POLLIN | POLLOUT;
|
||||||
FD_SET(h->fd, &wait_ctx->wfds);
|
|
||||||
break;
|
break;
|
||||||
case PROXYING:
|
case PROXYING:
|
||||||
if (_krb5_socks4a_reading(h->socks4a))
|
if (_krb5_socks4a_reading(h->socks4a))
|
||||||
FD_SET(h->fd, &wait_ctx->rfds);
|
events |= POLLIN;
|
||||||
if (_krb5_socks4a_writing(h->socks4a))
|
if (_krb5_socks4a_writing(h->socks4a))
|
||||||
FD_SET(h->fd, &wait_ctx->wfds);
|
events |= POLLOUT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
debug_host(wait_ctx->context, 5, h, "invalid sendto host state");
|
debug_host(wait_ctx->context, 5, h, "invalid sendto host state");
|
||||||
heim_abort("invalid sendto host state");
|
heim_abort("invalid sendto host state");
|
||||||
}
|
}
|
||||||
if (h->fd > wait_ctx->max_fd || wait_ctx->max_fd == rk_INVALID_SOCKET)
|
|
||||||
wait_ctx->max_fd = h->fd;
|
wait_ctx->pfds[wait_ctx->nfds].fd = h->fd;
|
||||||
|
wait_ctx->pfds[wait_ctx->nfds].events = events;
|
||||||
|
wait_ctx->pfds[wait_ctx->nfds].revents = 0;
|
||||||
|
|
||||||
|
wait_ctx->hosts[wait_ctx->nfds] = h;
|
||||||
|
wait_ctx->nfds++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1242,39 +1240,39 @@ wait_accelerate(heim_object_t obj, void *ctx, int *stop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wait_process(heim_object_t obj, void *ctx, int *stop)
|
wait_process(struct wait_ctx *wait_ctx)
|
||||||
{
|
{
|
||||||
struct wait_ctx *wait_ctx = ctx;
|
for (nfds_t i = 0; i < wait_ctx->nfds; i++) {
|
||||||
struct host *h = (struct host *)obj;
|
struct host *h = wait_ctx->hosts[i];
|
||||||
int readable, writeable;
|
struct pollfd *pfd = &wait_ctx->pfds[i];
|
||||||
heim_assert(h->state != DEAD, "dead host resurected");
|
|
||||||
|
|
||||||
#ifndef NO_LIMIT_FD_SETSIZE
|
int readable = pfd->revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL);
|
||||||
heim_assert(h->fd < FD_SETSIZE, "fd too large");
|
int writeable = pfd->revents & POLLOUT;
|
||||||
#endif
|
|
||||||
readable = FD_ISSET(h->fd, &wait_ctx->rfds);
|
|
||||||
writeable = FD_ISSET(h->fd, &wait_ctx->wfds);
|
|
||||||
|
|
||||||
if (readable || writeable || h->state == CONNECT)
|
if (readable || writeable || h->state == CONNECT)
|
||||||
wait_ctx->got_reply |= eval_host_state(wait_ctx->context, wait_ctx->ctx, h, readable, writeable);
|
wait_ctx->got_reply |= eval_host_state(
|
||||||
|
wait_ctx->context,
|
||||||
|
wait_ctx->ctx,
|
||||||
|
h,
|
||||||
|
readable,
|
||||||
|
writeable
|
||||||
|
);
|
||||||
|
|
||||||
/* if there is already a reply, just fall though the array */
|
|
||||||
if (wait_ctx->got_reply)
|
if (wait_ctx->got_reply)
|
||||||
*stop = 1;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
|
wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
|
||||||
{
|
{
|
||||||
struct wait_ctx wait_ctx;
|
struct wait_ctx wait_ctx;
|
||||||
struct timeval tv;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
memset(&wait_ctx, 0, sizeof(wait_ctx));
|
||||||
|
|
||||||
wait_ctx.context = context;
|
wait_ctx.context = context;
|
||||||
wait_ctx.ctx = ctx;
|
wait_ctx.ctx = ctx;
|
||||||
FD_ZERO(&wait_ctx.rfds);
|
|
||||||
FD_ZERO(&wait_ctx.wfds);
|
|
||||||
wait_ctx.max_fd = rk_INVALID_SOCKET;
|
|
||||||
|
|
||||||
/* oh, we have a reply, it must be a plugin that got it for us */
|
/* oh, we have a reply, it must be a plugin that got it for us */
|
||||||
if (ctx->response.length) {
|
if (ctx->response.length) {
|
||||||
@@ -1284,10 +1282,8 @@ wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
|
|||||||
|
|
||||||
wait_ctx.timenow = time(NULL);
|
wait_ctx.timenow = time(NULL);
|
||||||
|
|
||||||
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_setup);
|
size_t max_hosts = heim_array_get_length(ctx->hosts);
|
||||||
heim_array_filter_f(ctx->hosts, &wait_ctx, wait_filter_dead);
|
if (max_hosts == 0) {
|
||||||
|
|
||||||
if (heim_array_get_length(ctx->hosts) == 0) {
|
|
||||||
if (ctx->stateflags & KRBHST_COMPLETED) {
|
if (ctx->stateflags & KRBHST_COMPLETED) {
|
||||||
_krb5_debug(context, 5, "no more hosts to send/recv packets to/from "
|
_krb5_debug(context, 5, "no more hosts to send/recv packets to/from "
|
||||||
"trying to pulling more hosts");
|
"trying to pulling more hosts");
|
||||||
@@ -1300,7 +1296,18 @@ wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait_ctx.max_fd == rk_INVALID_SOCKET) {
|
wait_ctx.pfds = calloc(max_hosts, sizeof(struct pollfd));
|
||||||
|
wait_ctx.hosts = calloc(max_hosts, sizeof(struct host *));
|
||||||
|
if (!wait_ctx.pfds || !wait_ctx.hosts) {
|
||||||
|
free(wait_ctx.pfds);
|
||||||
|
free(wait_ctx.hosts);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
heim_array_filter_f(ctx->hosts, &wait_ctx, wait_filter_dead);
|
||||||
|
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_setup);
|
||||||
|
|
||||||
|
if (wait_ctx.nfds == 0) {
|
||||||
/*
|
/*
|
||||||
* If we don't find a host which can make progress, then
|
* If we don't find a host which can make progress, then
|
||||||
* we accelerate the process by moving all of the contestants
|
* we accelerate the process by moving all of the contestants
|
||||||
@@ -1308,27 +1315,36 @@ wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
|
|||||||
*/
|
*/
|
||||||
_krb5_debug(context, 5, "wait_response: moving the contestants forward");
|
_krb5_debug(context, 5, "wait_response: moving the contestants forward");
|
||||||
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_accelerate);
|
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_accelerate);
|
||||||
|
free(wait_ctx.pfds);
|
||||||
|
free(wait_ctx.hosts);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tv.tv_sec = 1;
|
ret = poll(wait_ctx.pfds, wait_ctx.nfds, 1000); /* 1s */
|
||||||
tv.tv_usec = 0;
|
|
||||||
|
|
||||||
ret = select(wait_ctx.max_fd + 1, &wait_ctx.rfds, &wait_ctx.wfds, NULL, &tv);
|
if (ret < 0) {
|
||||||
if (ret < 0)
|
free(wait_ctx.pfds);
|
||||||
|
free(wait_ctx.hosts);
|
||||||
return errno;
|
return errno;
|
||||||
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
*action = KRB5_SENDTO_TIMEOUT;
|
*action = KRB5_SENDTO_TIMEOUT;
|
||||||
|
free(wait_ctx.pfds);
|
||||||
|
free(wait_ctx.hosts);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_ctx.got_reply = 0;
|
wait_ctx.got_reply = 0;
|
||||||
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_process);
|
wait_process(&wait_ctx);
|
||||||
|
|
||||||
if (wait_ctx.got_reply)
|
if (wait_ctx.got_reply)
|
||||||
*action = KRB5_SENDTO_FILTER;
|
*action = KRB5_SENDTO_FILTER;
|
||||||
else
|
else
|
||||||
*action = KRB5_SENDTO_CONTINUE;
|
*action = KRB5_SENDTO_CONTINUE;
|
||||||
|
|
||||||
|
free(wait_ctx.pfds);
|
||||||
|
free(wait_ctx.hosts);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2294
-1
File diff suppressed because it is too large
Load Diff
@@ -239,10 +239,47 @@ check_escaped_strings(void)
|
|||||||
krb5_free_context(context);
|
krb5_free_context(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_dash_underscore(void)
|
||||||
|
{
|
||||||
|
krb5_context context;
|
||||||
|
krb5_config_section *c = NULL;
|
||||||
|
krb5_error_code ret;
|
||||||
|
const char *s;
|
||||||
|
char **ps;
|
||||||
|
|
||||||
|
ret = krb5_init_context(&context);
|
||||||
|
if (ret)
|
||||||
|
errx(1, "krb5_init_context %d", ret);
|
||||||
|
|
||||||
|
ret = krb5_config_parse_file(context, "test_config_strings.out", &c);
|
||||||
|
if (ret)
|
||||||
|
krb5_errx(context, 1, "krb5_config_parse_file()");
|
||||||
|
|
||||||
|
s = krb5_config_get_string(context, c, "dash-test", "final-value", NULL);
|
||||||
|
if (s == NULL || strcmp(s, "through-section") != 0)
|
||||||
|
errx(1, "dash/underscore lookup failed");
|
||||||
|
|
||||||
|
ps = krb5_config_get_strings(context, c, "dash-test", "same-name", NULL);
|
||||||
|
if (ps == NULL ||
|
||||||
|
ps[0] == NULL || strcmp(ps[0], "first") != 0 ||
|
||||||
|
ps[1] == NULL || strcmp(ps[1], "second") != 0 ||
|
||||||
|
ps[2] != NULL)
|
||||||
|
errx(1, "dash/underscore iteration failed");
|
||||||
|
krb5_config_free_strings(ps);
|
||||||
|
|
||||||
|
ret = krb5_config_file_free(context, c);
|
||||||
|
if (ret)
|
||||||
|
krb5_errx(context, 1, "krb5_config_file_free()");
|
||||||
|
|
||||||
|
krb5_free_context(context);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
check_config_files();
|
check_config_files();
|
||||||
check_escaped_strings();
|
check_escaped_strings();
|
||||||
|
check_dash_underscore();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,3 +10,8 @@
|
|||||||
internal2 = "TownOf Sandwich: Massachusetts"Oldest Town In "Cape Cod"
|
internal2 = "TownOf Sandwich: Massachusetts"Oldest Town In "Cape Cod"
|
||||||
internal3 = "Begins and"ends In One String
|
internal3 = "Begins and"ends In One String
|
||||||
longer_strings = "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 Institute 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 INSTITUTE 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 INSTITUTE 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." "Why do we test with such long strings? Because some people have config files" That look "Like this."
|
longer_strings = "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 Institute 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 INSTITUTE 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 INSTITUTE 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." "Why do we test with such long strings? Because some people have config files" That look "Like this."
|
||||||
|
|
||||||
|
[dash_test]
|
||||||
|
final_value = through-section
|
||||||
|
same_name = first
|
||||||
|
same-name = second
|
||||||
|
|||||||
@@ -63,6 +63,89 @@ test_empty_keytab(krb5_context context, const char *keytab)
|
|||||||
krb5_err(context, 1, ret, "krb5_kt_close");
|
krb5_err(context, 1, ret, "krb5_kt_close");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_verify_user_empty_keytab(krb5_context context, const char *keytab)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_keytab id;
|
||||||
|
krb5_principal principal;
|
||||||
|
krb5_verify_opt opt;
|
||||||
|
|
||||||
|
ret = krb5_kt_resolve(context, keytab, &id);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_kt_resolve");
|
||||||
|
|
||||||
|
ret = krb5_parse_name(context, "lha@SU.SE", &principal);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_parse_name");
|
||||||
|
|
||||||
|
krb5_verify_opt_init(&opt);
|
||||||
|
krb5_verify_opt_set_keytab(&opt, id);
|
||||||
|
|
||||||
|
ret = krb5_verify_user_opt(context, principal, "password", &opt);
|
||||||
|
if (ret != KRB5_KT_NOTFOUND)
|
||||||
|
krb5_errx(context, 1,
|
||||||
|
"krb5_verify_user_opt returned %d, expected %d",
|
||||||
|
(int)ret, (int)KRB5_KT_NOTFOUND);
|
||||||
|
|
||||||
|
krb5_free_principal(context, principal);
|
||||||
|
|
||||||
|
ret = krb5_kt_close(context, id);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_kt_close");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_verify_user_wrong_keytab(krb5_context context, const char *keytab)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_keytab id;
|
||||||
|
krb5_keytab_entry entry;
|
||||||
|
krb5_principal principal;
|
||||||
|
krb5_verify_opt opt;
|
||||||
|
|
||||||
|
ret = krb5_kt_resolve(context, keytab, &id);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_kt_resolve");
|
||||||
|
|
||||||
|
memset(&entry, 0, sizeof(entry));
|
||||||
|
ret = krb5_parse_name(context, "not-host/foo@SU.SE", &entry.principal);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_parse_name");
|
||||||
|
entry.vno = 1;
|
||||||
|
ret = krb5_generate_random_keyblock(context,
|
||||||
|
ETYPE_AES256_CTS_HMAC_SHA1_96,
|
||||||
|
&entry.keyblock);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
|
||||||
|
|
||||||
|
ret = krb5_kt_add_entry(context, id, &entry);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_kt_add_entry");
|
||||||
|
|
||||||
|
ret = krb5_parse_name(context, "lha@SU.SE", &principal);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_parse_name");
|
||||||
|
|
||||||
|
krb5_verify_opt_init(&opt);
|
||||||
|
krb5_verify_opt_set_keytab(&opt, id);
|
||||||
|
|
||||||
|
ret = krb5_verify_user_opt(context, principal, "password", &opt);
|
||||||
|
if (ret != KRB5_KT_NOTFOUND)
|
||||||
|
krb5_errx(context, 1,
|
||||||
|
"krb5_verify_user_opt returned %d, expected %d",
|
||||||
|
(int)ret, (int)KRB5_KT_NOTFOUND);
|
||||||
|
|
||||||
|
krb5_free_principal(context, principal);
|
||||||
|
krb5_kt_remove_entry(context, id, &entry);
|
||||||
|
krb5_free_principal(context, entry.principal);
|
||||||
|
krb5_free_keyblock_contents(context, &entry.keyblock);
|
||||||
|
|
||||||
|
ret = krb5_kt_close(context, id);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_kt_close");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test that memory keytab are refcounted.
|
* Test that memory keytab are refcounted.
|
||||||
*/
|
*/
|
||||||
@@ -281,6 +364,13 @@ main(int argc, char **argv)
|
|||||||
test_empty_keytab(context, "MEMORY:foo");
|
test_empty_keytab(context, "MEMORY:foo");
|
||||||
test_empty_keytab(context, "FILE:foo");
|
test_empty_keytab(context, "FILE:foo");
|
||||||
|
|
||||||
|
ret = krb5_set_default_realm(context, "SU.SE");
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_set_default_realm");
|
||||||
|
|
||||||
|
test_verify_user_empty_keytab(context, "MEMORY:verify-user-empty");
|
||||||
|
test_verify_user_wrong_keytab(context, "MEMORY:verify-user-wrong");
|
||||||
|
|
||||||
test_memory_keytab(context, "MEMORY:foo", "MEMORY:foo2");
|
test_memory_keytab(context, "MEMORY:foo", "MEMORY:foo2");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ check_set_time(krb5_context context)
|
|||||||
diff2 = krb5_time_abs(sec, tv.tv_sec);
|
diff2 = krb5_time_abs(sec, tv.tv_sec);
|
||||||
|
|
||||||
if (diff2 < 9 || diff > 11)
|
if (diff2 < 9 || diff > 11)
|
||||||
krb5_errx(context, 1, "set time error: diff: %ld",
|
krb5_errx(context, 1, "set time error: diff: %lld",
|
||||||
krb5_time_abs(sec, tv.tv_sec));
|
(long long)krb5_time_abs(sec, tv.tv_sec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+44
-1
@@ -33,6 +33,40 @@
|
|||||||
|
|
||||||
#include "krb5_locl.h"
|
#include "krb5_locl.h"
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
check_server_keytab(krb5_context context, krb5_keytab keytab,
|
||||||
|
const char *service)
|
||||||
|
{
|
||||||
|
krb5_error_code ret, ret2;
|
||||||
|
krb5_keytab_entry entry;
|
||||||
|
krb5_keytab kt = keytab;
|
||||||
|
krb5_principal server;
|
||||||
|
|
||||||
|
ret = krb5_sname_to_principal(context, NULL, service, KRB5_NT_SRV_HST,
|
||||||
|
&server);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (kt == NULL) {
|
||||||
|
ret = krb5_kt_default(context, &kt);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = krb5_kt_get_entry(context, kt, server, 0, 0, &entry);
|
||||||
|
if (ret == 0)
|
||||||
|
krb5_kt_free_entry(context, &entry);
|
||||||
|
if (keytab == NULL) {
|
||||||
|
ret2 = krb5_kt_close(context, kt);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = ret2;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
krb5_free_principal(context, server);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
verify_common (krb5_context context,
|
verify_common (krb5_context context,
|
||||||
krb5_principal principal,
|
krb5_principal principal,
|
||||||
@@ -185,7 +219,16 @@ krb5_verify_user_opt(krb5_context context,
|
|||||||
const char *password,
|
const char *password,
|
||||||
krb5_verify_opt *opt)
|
krb5_verify_opt *opt)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret = 0;
|
||||||
|
|
||||||
|
#define OPT(V, D) ((opt && (opt->V)) ? (opt->V) : (D))
|
||||||
|
if (opt == NULL || opt->secure) {
|
||||||
|
ret = check_server_keytab(context, OPT(keytab, NULL),
|
||||||
|
OPT(service, "host"));
|
||||||
|
}
|
||||||
|
#undef OPT
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if(opt && (opt->flags & KRB5_VERIFY_LREALMS)) {
|
if(opt && (opt->flags & KRB5_VERIFY_LREALMS)) {
|
||||||
krb5_realm *realms, *r;
|
krb5_realm *realms, *r;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user