Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
845fb73ad1
|
|||
|
d0b5821e9a
|
|||
|
072c1f062f
|
@@ -3,7 +3,6 @@ name: Test Coverage
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
|
||||||
- 'coverage-*'
|
- 'coverage-*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -37,7 +36,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap --prefix=$HOME/inst CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap --prefix=$HOME/inst CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 40
|
|
||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
sudo sysctl kernel.core_pattern=core.%p || true
|
sudo sysctl kernel.core_pattern=core.%p || true
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ jobs:
|
|||||||
cd build
|
cd build
|
||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
||||||
ulimit -c unlimited
|
ulimit -c unlimited
|
||||||
# We don't want to scan-build SQLite3 because ETOOSLOW
|
# We don't want to scan-build libedit nor SQLite3 because ETOOSLOW
|
||||||
|
(cd lib/libedit && make -j4)
|
||||||
(cd lib/sqlite && make -j4)
|
(cd lib/sqlite && make -j4)
|
||||||
cov-build --dir cov-int make -j4
|
cov-build --dir cov-int make -j4
|
||||||
tar czvf ../heimdal.tgz cov-int
|
tar czvf ../heimdal.tgz cov-int
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations" --with-mitkrb5=$HOME/mitkrb5 --with-older-heimdal=$HOME/oh5l
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations" --with-mitkrb5=$HOME/mitkrb5 --with-older-heimdal=$HOME/oh5l
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 20
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'master'
|
||||||
- 'heimdal-7-1-branch'
|
- 'heimdal-7-1-branch'
|
||||||
- 'test-ILP32'
|
|
||||||
paths:
|
paths:
|
||||||
- '!docs/**'
|
- '!docs/**'
|
||||||
- '!**.md'
|
- '!**.md'
|
||||||
@@ -64,7 +63,6 @@ jobs:
|
|||||||
os: ubuntu-22.04
|
os: ubuntu-22.04
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
cflags: '-Wnonnull'
|
cflags: '-Wnonnull'
|
||||||
configureopts: '--with-readline=yes'
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -75,7 +73,7 @@ jobs:
|
|||||||
sudo apt-get install -y bison comerr-dev flex doxygen
|
sudo apt-get install -y bison comerr-dev flex doxygen
|
||||||
sudo apt-get install -y libcap-ng-dev libdb-dev libedit-dev libjson-perl
|
sudo apt-get install -y libcap-ng-dev libdb-dev libedit-dev libjson-perl
|
||||||
sudo apt-get install -y libldap2-dev libncurses5-dev libperl4-corelibs-perl
|
sudo apt-get install -y libldap2-dev libncurses5-dev libperl4-corelibs-perl
|
||||||
sudo apt-get install -y libsqlite3-dev libkeyutils-dev libreadline-dev pkg-config python3
|
sudo apt-get install -y libsqlite3-dev libkeyutils-dev pkg-config python3
|
||||||
sudo apt-get install -y ss-dev texinfo unzip netbase keyutils ldap-utils
|
sudo apt-get install -y ss-dev texinfo unzip netbase keyutils ldap-utils
|
||||||
sudo apt-get install -y gdb apport curl libmicrohttpd-dev jq valgrind
|
sudo apt-get install -y gdb apport curl libmicrohttpd-dev jq valgrind
|
||||||
# Temporary workaround for:
|
# Temporary workaround for:
|
||||||
@@ -85,7 +83,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
CONFIGURE_OPTS: ${{ matrix.configureopts }}
|
|
||||||
run: |
|
run: |
|
||||||
/bin/sh ./autogen.sh
|
/bin/sh ./autogen.sh
|
||||||
mkdir build
|
mkdir build
|
||||||
@@ -93,7 +90,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 40
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
@@ -111,27 +107,6 @@ jobs:
|
|||||||
make DESTDIR=/tmp/h5l install
|
make DESTDIR=/tmp/h5l install
|
||||||
cd /tmp/h5l
|
cd /tmp/h5l
|
||||||
tar czf $HOME/heimdal-install-linux-${{ matrix.compiler }}.tgz .
|
tar czf $HOME/heimdal-install-linux-${{ matrix.compiler }}.tgz .
|
||||||
- name: Interrupted/timed out test diagnostics
|
|
||||||
if: ${{ cancelled() || failure() }}
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
# Show any test-related processes still running
|
|
||||||
ps auxww | grep -E 'kdc|test_context|kinit|kadmin|check-' | grep -v grep || true
|
|
||||||
# Show who's on the test port
|
|
||||||
ss -tlnp sport = :49188 || true
|
|
||||||
# Show the newest .log file (the one likely interrupted)
|
|
||||||
newest=$(find build/tests -name '*.log' -newer build/tests/gss/Makefile -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
|
||||||
if [ -n "$newest" ]; then
|
|
||||||
echo "=== Newest test log: $newest ==="
|
|
||||||
cat "$newest"
|
|
||||||
fi
|
|
||||||
# Also show KDC messages.log if any exist
|
|
||||||
for f in build/tests/gss/messages.log build/tests/kdc/messages.log; do
|
|
||||||
if [ -f "$f" ]; then
|
|
||||||
echo "=== $f ==="
|
|
||||||
tail -100 "$f"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
- name: Core dump stacks
|
- name: Core dump stacks
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
run: |
|
run: |
|
||||||
@@ -172,75 +147,3 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: Test Logs (${{ matrix.name }})
|
name: Test Logs (${{ matrix.name }})
|
||||||
path: '~/logs-linux-${{ matrix.compiler }}.tgz'
|
path: '~/logs-linux-${{ matrix.compiler }}.tgz'
|
||||||
|
|
||||||
linux-i386:
|
|
||||||
name: linux-i386 (${{ matrix.name }})
|
|
||||||
# Run if no [only X] tag, or if [only linux] is present (check both push commits and PR titles)
|
|
||||||
if: >-
|
|
||||||
(!contains(github.event.head_commit.message, '[only ') &&
|
|
||||||
!contains(github.event.pull_request.title, '[only ')) ||
|
|
||||||
contains(github.event.head_commit.message, '[only linux]') ||
|
|
||||||
contains(github.event.pull_request.title, '[only linux]')
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- name: time32
|
|
||||||
image: i386/debian:bookworm
|
|
||||||
year2038_configure: ""
|
|
||||||
time_t_size: 4
|
|
||||||
- name: year2038
|
|
||||||
image: i386/debian:trixie
|
|
||||||
year2038_configure: --enable-year2038
|
|
||||||
time_t_size: 8
|
|
||||||
steps:
|
|
||||||
- name: Clone repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Build and test on Debian i386
|
|
||||||
run: |
|
|
||||||
docker run --security-opt seccomp=unconfined --platform linux/386 --rm \
|
|
||||||
-v "$PWD:/src:ro" \
|
|
||||||
-e YEAR2038_CONFIGURE="${{ matrix.year2038_configure }}" \
|
|
||||||
-e EXPECT_TIME_T_SIZE="${{ matrix.time_t_size }}" \
|
|
||||||
${{ matrix.image }} \
|
|
||||||
/bin/bash -euxc '
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
apt-get update -qq
|
|
||||||
apt-get install -y --no-install-recommends \
|
|
||||||
autoconf automake bison build-essential ca-certificates \
|
|
||||||
comerr-dev curl doxygen flex gdb git iproute2 jq keyutils \
|
|
||||||
ldap-utils libcap-ng-dev libdb-dev libedit-dev libjson-perl \
|
|
||||||
libkeyutils-dev libldap2-dev liblmdb-dev libmicrohttpd-dev libncurses5-dev \
|
|
||||||
libperl4-corelibs-perl libreadline-dev libsqlite3-dev libssl-dev \
|
|
||||||
libtool make netbase pkg-config procps python3 ss-dev tar \
|
|
||||||
texinfo unzip valgrind xz-utils
|
|
||||||
|
|
||||||
cp -a /src /tmp/heimdal-src
|
|
||||||
git config --global --add safe.directory /tmp/heimdal-src
|
|
||||||
cd /tmp/heimdal-src
|
|
||||||
/bin/sh ./autogen.sh
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
../configure --srcdir=`dirname "$PWD"` \
|
|
||||||
--enable-maintainer-mode \
|
|
||||||
--enable-developer \
|
|
||||||
${YEAR2038_CONFIGURE} \
|
|
||||||
--with-ldap \
|
|
||||||
--with-readline=yes \
|
|
||||||
--with-db-type-preference=lmdb \
|
|
||||||
--prefix=/tmp/heimdal-i386-inst \
|
|
||||||
CFLAGS="-Wnonnull -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
|
||||||
printf "%s\n" \
|
|
||||||
"#include \"include/config.h\"" \
|
|
||||||
"#include <stdio.h>" \
|
|
||||||
"#include <time.h>" \
|
|
||||||
"int main(void) { unsigned long s = sizeof(time_t); printf(\"sizeof(time_t)=%lu\n\", s); return s == EXPECT_TIME_T_SIZE ? 0 : 1; }" \
|
|
||||||
> check-time-t.c
|
|
||||||
cc -I. -I.. -DEXPECT_TIME_T_SIZE="$EXPECT_TIME_T_SIZE" -o check-time-t check-time-t.c
|
|
||||||
./check-time-t
|
|
||||||
make -j4
|
|
||||||
make -C lib/asn1 check
|
|
||||||
make -C lib/hx509 check TESTS=test_cert_binary
|
|
||||||
make DESTDIR=/tmp/heimdal-i386-root install
|
|
||||||
'
|
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ jobs:
|
|||||||
- name: osx-clang
|
- name: osx-clang
|
||||||
os: macos-latest
|
os: macos-latest
|
||||||
compiler: clang
|
compiler: clang
|
||||||
configureopts: '--with-libedit=yes'
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: |
|
run: |
|
||||||
@@ -94,7 +93,6 @@ jobs:
|
|||||||
# with:
|
# with:
|
||||||
# limit-access-to-actor: true
|
# limit-access-to-actor: true
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 25
|
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
@@ -107,27 +105,6 @@ jobs:
|
|||||||
sudo lsof -nP -i:49188 || true
|
sudo lsof -nP -i:49188 || true
|
||||||
cd build
|
cd build
|
||||||
make check
|
make check
|
||||||
- name: Interrupted/timed out test diagnostics
|
|
||||||
if: ${{ cancelled() || failure() }}
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
# Show any test-related processes still running
|
|
||||||
ps auxww | grep -E 'kdc|test_context|kinit|kadmin|check-' | grep -v grep || true
|
|
||||||
# Show who's on the test port
|
|
||||||
sudo lsof -nP -i:49188 || true
|
|
||||||
# Show the newest .log file (the one likely interrupted)
|
|
||||||
newest=$(find build/tests -name '*.log' -newer build/tests/gss/Makefile -print0 2>/dev/null | xargs -0 stat -f '%m %N' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
|
||||||
if [ -n "$newest" ]; then
|
|
||||||
echo "=== Newest test log: $newest ==="
|
|
||||||
cat "$newest"
|
|
||||||
fi
|
|
||||||
# Also show KDC messages.log if any exist
|
|
||||||
for f in build/tests/gss/messages.log build/tests/kdc/messages.log; do
|
|
||||||
if [ -f "$f" ]; then
|
|
||||||
echo "=== $f ==="
|
|
||||||
tail -100 "$f"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: |
|
run: |
|
||||||
cd build || true
|
cd build || true
|
||||||
@@ -135,7 +112,6 @@ jobs:
|
|||||||
cd /tmp/h5l
|
cd /tmp/h5l
|
||||||
tar czf $HOME/heimdal-install-osx.tgz .
|
tar czf $HOME/heimdal-install-osx.tgz .
|
||||||
- name: Test logs
|
- name: Test logs
|
||||||
if: ${{ always() }}
|
|
||||||
run: |
|
run: |
|
||||||
find build -depth -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/' | cpio -o > $HOME/logs-osx.cpio
|
find build -depth -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/' | cpio -o > $HOME/logs-osx.cpio
|
||||||
find build -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/'|xargs cat
|
find build -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/'|xargs cat
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ jobs:
|
|||||||
cd build
|
cd build
|
||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
||||||
ulimit -c unlimited
|
ulimit -c unlimited
|
||||||
# We don't want to scan-build SQLite3 because ETOOSLOW
|
# We don't want to scan-build libedit nor SQLite3 because ETOOSLOW
|
||||||
|
(cd lib/libedit && make -j4)
|
||||||
(cd lib/sqlite && make -j4)
|
(cd lib/sqlite && make -j4)
|
||||||
scan-build --keep-going make -j4
|
scan-build --keep-going make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 40
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --enable-dynamic --disable-static --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations" LDFLAGS="${{ matrix.ldflags }}"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --enable-dynamic --disable-static --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="${{ matrix.cflags }} -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations" LDFLAGS="${{ matrix.ldflags }}"
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 80
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ jobs:
|
|||||||
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-gdwarf-4 -g -ggdb3 -O0 -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-gdwarf-4 -g -ggdb3 -O0 -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
|
||||||
make -j4
|
make -j4
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 120
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
MAKEVARS: ${{ matrix.makevars }}
|
MAKEVARS: ${{ matrix.makevars }}
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ jobs:
|
|||||||
)
|
)
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
timeout-minutes: 20
|
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
set "PATH=%PATH%;C:\msys64\usr\bin"
|
set "PATH=%PATH%;C:\msys64\usr\bin"
|
||||||
|
|||||||
+26
-3
@@ -64,6 +64,32 @@ asn1_*_asn1.c
|
|||||||
/tmp.h
|
/tmp.h
|
||||||
/ylwrap
|
/ylwrap
|
||||||
|
|
||||||
|
/lib/libedit/aclocal.m4
|
||||||
|
/lib/libedit/autom4te.cache
|
||||||
|
/lib/libedit/compile
|
||||||
|
/lib/libedit/config.guess
|
||||||
|
/lib/libedit/config.h
|
||||||
|
/lib/libedit/config.log
|
||||||
|
/lib/libedit/config.status
|
||||||
|
/lib/libedit/config.sub
|
||||||
|
/lib/libedit/configure
|
||||||
|
/lib/libedit/depcomp
|
||||||
|
/lib/libedit/install-sh
|
||||||
|
/lib/libedit/libtool
|
||||||
|
/lib/libedit/ltmain.sh
|
||||||
|
/lib/libedit/missing
|
||||||
|
/lib/libedit/setupbuild.cmd
|
||||||
|
/lib/libedit/ylwrap
|
||||||
|
/lib/libedit/src/common.h
|
||||||
|
/lib/libedit/src/emacs.h
|
||||||
|
/lib/libedit/src/fcns.c
|
||||||
|
/lib/libedit/src/fcns.h
|
||||||
|
/lib/libedit/src/func.h
|
||||||
|
/lib/libedit/src/help.c
|
||||||
|
/lib/libedit/src/help.h
|
||||||
|
/lib/libedit/src/vi.h
|
||||||
|
/lib/libedit/stamp-h1
|
||||||
|
|
||||||
# Files in subdirectories.
|
# Files in subdirectories.
|
||||||
|
|
||||||
/admin/ktutil
|
/admin/ktutil
|
||||||
@@ -694,6 +720,3 @@ asn1_*_asn1.c
|
|||||||
/tools/krb5-gssapi.pc
|
/tools/krb5-gssapi.pc
|
||||||
/tools/krb5.pc
|
/tools/krb5.pc
|
||||||
/tools/krb5-config
|
/tools/krb5-config
|
||||||
|
|
||||||
result
|
|
||||||
result-*
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ Release Notes - Heimdal - Version Heimdal 8.0 (future)
|
|||||||
- Errors found by the LLVM scan-build static analyzer.
|
- Errors found by the LLVM scan-build static analyzer.
|
||||||
- Errors found by the valgrind memory debugger.
|
- Errors found by the valgrind memory debugger.
|
||||||
- Fix out-of-tree SQLite3 ccache permissions / umask issues.
|
- Fix out-of-tree SQLite3 ccache permissions / umask issues.
|
||||||
- Clamp far-future ASN.1 times on 32-bit time_t platforms instead of wrapping.
|
|
||||||
- iprop bugs, race conditions, and performance
|
- iprop bugs, race conditions, and performance
|
||||||
- Many misc. bugs
|
- Many misc. bugs
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
||||||
[](https://coveralls.io/github/heimdal/heimdal?branch=master)
|
|
||||||
|
|
||||||
Heimdal
|
Heimdal
|
||||||
=======
|
=======
|
||||||
@@ -34,4 +33,3 @@ Build Status
|
|||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
||||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
||||||
[](https://coveralls.io/github/heimdal/heimdal?branch=master)
|
|
||||||
|
|||||||
+27
-50
@@ -43,9 +43,6 @@ kt_rename(struct rename_options *opt, int argc, char **argv)
|
|||||||
krb5_keytab keytab;
|
krb5_keytab keytab;
|
||||||
krb5_kt_cursor cursor;
|
krb5_kt_cursor cursor;
|
||||||
krb5_principal from_princ, to_princ;
|
krb5_principal from_princ, to_princ;
|
||||||
krb5_keytab_entry *entries = NULL;
|
|
||||||
size_t num_entries = 0;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
ret = krb5_parse_name(context, argv[0], &from_princ);
|
ret = krb5_parse_name(context, argv[0], &from_princ);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
@@ -66,14 +63,6 @@ kt_rename(struct rename_options *opt, int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Collect matching entries first, then close the cursor before
|
|
||||||
* adding/removing. We must not call krb5_kt_add_entry() or
|
|
||||||
* krb5_kt_remove_entry() while holding the seq_get cursor because
|
|
||||||
* the cursor holds a shared file lock and the add/remove operations
|
|
||||||
* need an exclusive lock -- with per-fd locking (BSD flock, OFD locks)
|
|
||||||
* this self-deadlocks.
|
|
||||||
*/
|
|
||||||
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
|
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
krb5_kt_close(context, keytab);
|
krb5_kt_close(context, keytab);
|
||||||
@@ -81,52 +70,40 @@ kt_rename(struct rename_options *opt, int argc, char **argv)
|
|||||||
krb5_free_principal(context, to_princ);
|
krb5_free_principal(context, to_princ);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
|
while(1) {
|
||||||
if(krb5_principal_compare(context, entry.principal, from_princ)) {
|
ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
|
||||||
krb5_keytab_entry *tmp;
|
if(ret != 0) {
|
||||||
|
if(ret != KRB5_CC_END && ret != KRB5_KT_END)
|
||||||
tmp = realloc(entries, (num_entries + 1) * sizeof(*entries));
|
krb5_warn(context, ret, "getting entry from keytab");
|
||||||
if (tmp == NULL) {
|
else
|
||||||
krb5_kt_free_entry(context, &entry);
|
ret = 0;
|
||||||
ret = krb5_enomem(context);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
entries = tmp;
|
|
||||||
krb5_free_principal(context, entry.principal);
|
|
||||||
entry.principal = NULL;
|
|
||||||
entries[num_entries++] = entry;
|
|
||||||
} else {
|
|
||||||
krb5_kt_free_entry(context, &entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(ret == KRB5_CC_END || ret == KRB5_KT_END)
|
|
||||||
ret = 0;
|
|
||||||
else if(ret)
|
|
||||||
krb5_warn(context, ret, "getting entry from keytab");
|
|
||||||
krb5_kt_end_seq_get(context, keytab, &cursor);
|
|
||||||
|
|
||||||
for (i = 0; ret == 0 && i < num_entries; i++) {
|
|
||||||
entries[i].principal = to_princ;
|
|
||||||
ret = krb5_kt_add_entry(context, keytab, &entries[i]);
|
|
||||||
if(ret) {
|
|
||||||
krb5_warn(context, ret, "adding entry");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (opt->delete_flag) {
|
if(krb5_principal_compare(context, entry.principal, from_princ)) {
|
||||||
entries[i].principal = from_princ;
|
krb5_free_principal(context, entry.principal);
|
||||||
ret = krb5_kt_remove_entry(context, keytab, &entries[i]);
|
entry.principal = to_princ;
|
||||||
|
ret = krb5_kt_add_entry(context, keytab, &entry);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
krb5_warn(context, ret, "removing entry");
|
entry.principal = NULL;
|
||||||
|
krb5_kt_free_entry(context, &entry);
|
||||||
|
krb5_warn(context, ret, "adding entry");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (opt->delete_flag) {
|
||||||
|
entry.principal = from_princ;
|
||||||
|
ret = krb5_kt_remove_entry(context, keytab, &entry);
|
||||||
|
if(ret) {
|
||||||
|
entry.principal = NULL;
|
||||||
|
krb5_kt_free_entry(context, &entry);
|
||||||
|
krb5_warn(context, ret, "removing entry");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entry.principal = NULL;
|
||||||
}
|
}
|
||||||
|
krb5_kt_free_entry(context, &entry);
|
||||||
}
|
}
|
||||||
|
krb5_kt_end_seq_get(context, keytab, &cursor);
|
||||||
for (i = 0; i < num_entries; i++) {
|
|
||||||
entries[i].principal = NULL;
|
|
||||||
krb5_kt_free_entry(context, &entries[i]);
|
|
||||||
}
|
|
||||||
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_vers) $(LIB_heimbase) $(LIB_roken)
|
LDADD = $(LIB_roken) $(LIB_vers) $(LIB_heimbase)
|
||||||
|
|||||||
@@ -57,9 +57,6 @@ AS_IF([test "x$with_berkeley_db" != xno],
|
|||||||
db.h \
|
db.h \
|
||||||
])])
|
])])
|
||||||
|
|
||||||
dnl detect if compat db_185.h is present
|
|
||||||
AC_CHECK_HEADERS([db_185.h])
|
|
||||||
|
|
||||||
dnl db_create is used by db3 and db4 and db5 and db6
|
dnl db_create is used by db3 and db4 and db5 and db6
|
||||||
|
|
||||||
AC_FIND_FUNC_NO_LIBS(db_create, [$dbheader] db-6 db-5 db4 db3 db, [
|
AC_FIND_FUNC_NO_LIBS(db_create, [$dbheader] db-6 db-5 db4 db3 db, [
|
||||||
|
|||||||
+11
-71
@@ -9,80 +9,20 @@ AC_DEFUN([KRB_READLINE],[
|
|||||||
|
|
||||||
dnl readline
|
dnl readline
|
||||||
|
|
||||||
readline_requested="${with_readline-unset}"
|
ac_foo=no
|
||||||
libedit_requested="${with_libedit-unset}"
|
build_editline=no
|
||||||
have_readline=no
|
|
||||||
|
|
||||||
rk_TEST_PACKAGE(readline,
|
|
||||||
[#include <stdio.h>
|
|
||||||
#if defined(HAVE_READLINE_READLINE_H)
|
|
||||||
#include <readline/readline.h>
|
|
||||||
#elif defined(HAVE_READLINE_H)
|
|
||||||
#include <readline.h>
|
|
||||||
#endif
|
|
||||||
],-lreadline,[$LIB_tgetent],,[READLINE],, [readline.h readline/readline.h])
|
|
||||||
|
|
||||||
rk_TEST_PACKAGE(libedit,
|
|
||||||
[#include <stdio.h>
|
|
||||||
#if defined(HAVE_EDITLINE_READLINE_H)
|
|
||||||
#include <editline/readline.h>
|
|
||||||
#elif defined(HAVE_READLINE_READLINE_H)
|
|
||||||
#include <readline/readline.h>
|
|
||||||
#elif defined(HAVE_READLINE_H)
|
|
||||||
#include <readline.h>
|
|
||||||
#endif
|
|
||||||
],-ledit,[$LIB_tgetent],,[READLINE],,
|
|
||||||
[readline.h readline/readline.h editline/readline.h])
|
|
||||||
|
|
||||||
if test "$with_readline" = yes; then
|
if test "$with_readline" = yes; then
|
||||||
have_readline=yes
|
:
|
||||||
elif test "$with_libedit" = yes; then
|
elif test "$with_libedit" = yes; then
|
||||||
INCLUDE_readline="${INCLUDE_libedit}"
|
LIB_readline="${LIB_libedit}"
|
||||||
LIB_readline="${LIB_libedit}"
|
elif test "$ac_cv_func_readline" = yes; then
|
||||||
have_readline=yes
|
:
|
||||||
elif test "$readline_requested" != no; then
|
|
||||||
rk_readline_header=no
|
|
||||||
AC_CHECK_HEADERS([readline/readline.h readline.h],
|
|
||||||
[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
|
|
||||||
|
|
||||||
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
|
|
||||||
AC_DEFINE(READLINE, 1, [Define if you have the readline package.])dnl
|
|
||||||
else
|
else
|
||||||
INCLUDE_readline=
|
build_libedit=yes
|
||||||
LIB_readline=
|
LIB_readline="\$(top_builddir)/lib/libedit/src/libheimedit.la \$(LIB_tgetent)"
|
||||||
AC_MSG_NOTICE([readline/libedit not found; command line editing disabled])
|
|
||||||
fi
|
fi
|
||||||
|
AM_CONDITIONAL(LIBEDIT, test "$build_libedit" = yes)
|
||||||
AC_SUBST(INCLUDE_readline)
|
AC_DEFINE(HAVE_READLINE, 1,
|
||||||
AC_SUBST(LIB_readline)
|
[Define if you have a readline compatible library.])dnl
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -19,10 +19,4 @@ if test "$enable_largefile" != no; then
|
|||||||
[CPPFLAGS="$CPPFLAGS $ac_cv_sys_largefile_opts"])
|
[CPPFLAGS="$CPPFLAGS $ac_cv_sys_largefile_opts"])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if test "$enable_year2038" != no; then
|
|
||||||
if test -n "$ac_cv_sys_year2038_opts"; then
|
|
||||||
AS_CASE([$ac_cv_sys_year2038_opts],[-D_TIME_BITS=*|-D__MINGW_USE_VC2005_COMPAT],
|
|
||||||
[CPPFLAGS="$CPPFLAGS $ac_cv_sys_year2038_opts"])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
])
|
])
|
||||||
|
|||||||
+1
-2
@@ -192,6 +192,7 @@ AC_CHECK_FUNCS([ \
|
|||||||
mkdtemp \
|
mkdtemp \
|
||||||
mkostemp \
|
mkostemp \
|
||||||
on_exit \
|
on_exit \
|
||||||
|
poll \
|
||||||
random \
|
random \
|
||||||
secure_getenv \
|
secure_getenv \
|
||||||
setprogname \
|
setprogname \
|
||||||
@@ -359,8 +360,6 @@ AC_BROKEN([ \
|
|||||||
mergesort \
|
mergesort \
|
||||||
mergesort_r \
|
mergesort_r \
|
||||||
mkstemp \
|
mkstemp \
|
||||||
poll \
|
|
||||||
pread \
|
|
||||||
putenv \
|
putenv \
|
||||||
rcmd \
|
rcmd \
|
||||||
readv \
|
readv \
|
||||||
|
|||||||
+4
-4
@@ -24,8 +24,8 @@ AC_ARG_WITH($1-config,
|
|||||||
AS_HELP_STRING([--with-$1-config=path],[config program for $1]))
|
AS_HELP_STRING([--with-$1-config=path],[config program for $1]))
|
||||||
|
|
||||||
m4_ifval([$6],
|
m4_ifval([$6],
|
||||||
[m4_define([rk_pkgname], [$6])],
|
m4_define([rk_pkgname], $6),
|
||||||
[m4_define([rk_pkgname], [AS_TR_CPP($1)])])
|
m4_define([rk_pkgname], AS_TR_CPP($1)))
|
||||||
|
|
||||||
AC_MSG_CHECKING(for $1)
|
AC_MSG_CHECKING(for $1)
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ if test "$with_$1" != no; then
|
|||||||
if test "$[]$1_cflags" -a "$[]$1_libs"; then
|
if test "$[]$1_cflags" -a "$[]$1_libs"; then
|
||||||
CFLAGS="$[]$1_cflags $save_CFLAGS"
|
CFLAGS="$[]$1_cflags $save_CFLAGS"
|
||||||
LIBS="$[]$1_libs $save_LIBS"
|
LIBS="$[]$1_libs $save_LIBS"
|
||||||
m4_ifval([$8],[AC_CHECK_HEADERS([$8])])
|
m4_ifval([$8],[AC_CHECK_HEADERS([[$8]])])
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[
|
||||||
INCLUDE_$1="$[]$1_cflags"
|
INCLUDE_$1="$[]$1_cflags"
|
||||||
LIB_$1="$[]$1_libs"
|
LIB_$1="$[]$1_libs"
|
||||||
@@ -102,7 +102,7 @@ if test "$with_$1" != no; then
|
|||||||
ires= lres=
|
ires= lres=
|
||||||
for i in $header_dirs; do
|
for i in $header_dirs; do
|
||||||
CFLAGS="-I$i $save_CFLAGS"
|
CFLAGS="-I$i $save_CFLAGS"
|
||||||
m4_ifval([$8],[AC_CHECK_HEADERS([$8])])
|
m4_ifval([$8],[AC_CHECK_HEADERS([[$8]])])
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[ires=$i;break])
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[ires=$i;break])
|
||||||
done
|
done
|
||||||
for i in $lib_dirs; do
|
for i in $lib_dirs; do
|
||||||
|
|||||||
@@ -382,6 +382,28 @@ AC_SUBST(ENABLE_AFS_STRING_TO_KEY)dnl
|
|||||||
|
|
||||||
rk_CHECK_MAN
|
rk_CHECK_MAN
|
||||||
|
|
||||||
|
rk_TEST_PACKAGE(readline,
|
||||||
|
[#include <stdio.h>
|
||||||
|
#if defined(HAVE_READLINE_READLINE_H)
|
||||||
|
#include <readline/readline.h>
|
||||||
|
#elif defined(HAVE_READLINE_H)
|
||||||
|
#include <readline.h>
|
||||||
|
#endif
|
||||||
|
],-lreadline,,, READLINE,, [readline.h readline/readline.h])
|
||||||
|
|
||||||
|
rk_TEST_PACKAGE(libedit,
|
||||||
|
[#include <stdio.h>
|
||||||
|
#if defined(HAVE_READLINE_READLINE_H)
|
||||||
|
#include <readline/readline.h>
|
||||||
|
#elif defined(HAVE_READLINE_H)
|
||||||
|
#include <readline.h>
|
||||||
|
#elif defined(HAVE_EDITLINE_READLINE_H)
|
||||||
|
#include <editline/readline.h>
|
||||||
|
#endif
|
||||||
|
],-ledit,,, READLINE,, [readline.h readline/readline.h editline/readline.h])
|
||||||
|
|
||||||
|
AC_CONFIG_SUBDIRS([lib/libedit])
|
||||||
|
|
||||||
KRB_C_BIGENDIAN
|
KRB_C_BIGENDIAN
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ The @code{popper} was also a Berkeley program initially.
|
|||||||
Some of the functions in @file{libroken} also come from Berkeley by way
|
Some of the functions in @file{libroken} also come from Berkeley by way
|
||||||
of NetBSD/FreeBSD.
|
of NetBSD/FreeBSD.
|
||||||
|
|
||||||
|
@code{editline} was written by Simmule Turner and Rich Salz. Heimdal
|
||||||
|
contains a modifed copy.
|
||||||
|
|
||||||
The @code{getifaddrs} implementation for Linux was written by Hideaki
|
The @code{getifaddrs} implementation for Linux was written by Hideaki
|
||||||
YOSHIFUJI for the Usagi project.
|
YOSHIFUJI for the Usagi project.
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,48 @@ SUCH DAMAGE.
|
|||||||
@end verbatim
|
@end verbatim
|
||||||
@copynext
|
@copynext
|
||||||
|
|
||||||
|
@heading The Regents of the University of California.
|
||||||
|
|
||||||
|
libedit
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
Copyright (c) 1992, 1993
|
||||||
|
The Regents of the University of California. All rights reserved.
|
||||||
|
|
||||||
|
This code is derived from software contributed to Berkeley by
|
||||||
|
Christos Zoulas of Cornell University.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the University nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
@end verbatim
|
||||||
|
@copynext
|
||||||
|
|
||||||
|
@copynext
|
||||||
|
|
||||||
@heading Doug Rabson
|
@heading Doug Rabson
|
||||||
|
|
||||||
GSS-API mechglue layer.
|
GSS-API mechglue layer.
|
||||||
|
|||||||
Generated
+3
-3
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770380644,
|
"lastModified": 1742800061,
|
||||||
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
|
"narHash": "sha256-oDJGK1UMArK52vcW9S5S2apeec4rbfNELgc50LqiPNs=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "ae67888ff7ef9dff69b3cf0cc0fbfbcd3a722abe",
|
"rev": "1750f3c1c89488e2ffdd47cab9d05454dddfb734",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -22,27 +22,13 @@
|
|||||||
default = pkgs.callPackage ./nix/shell.nix { };
|
default = pkgs.callPackage ./nix/shell.nix { };
|
||||||
});
|
});
|
||||||
|
|
||||||
packages = forAllSystems (system: pkgs: let
|
packages = forAllSystems (system: pkgs: with pkgs; {
|
||||||
src = lib.fileset.toSource {
|
|
||||||
root = ./.;
|
|
||||||
fileset = lib.fileset.difference ./. (lib.fileset.unions [
|
|
||||||
./.github
|
|
||||||
./.gitignore
|
|
||||||
./.zed
|
|
||||||
./flake.nix
|
|
||||||
./flake.lock
|
|
||||||
./nix
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
default = self.packages.${system}.heimdal;
|
default = self.packages.${system}.heimdal;
|
||||||
|
|
||||||
src = pkgs.runCommand "heimdal-src" {} "ln -s ${src} \"$out\"";
|
heimdal = pkgs.callPackage ./nix/heimdal {
|
||||||
|
src = lib.cleanSource ./.;
|
||||||
heimdal = pkgs.callPackage ./nix/heimdal/package.nix {
|
|
||||||
inherit src;
|
|
||||||
inherit (pkgs.darwin.apple_sdk.frameworks) CoreFoundation Security SystemConfiguration;
|
inherit (pkgs.darwin.apple_sdk.frameworks) CoreFoundation Security SystemConfiguration;
|
||||||
autoreconfHook = pkgs.buildPackages.autoreconfHook271;
|
autoreconfHook = pkgs.buildPackages.autoreconfHook269;
|
||||||
};
|
};
|
||||||
|
|
||||||
nixosTest = pkgs.testers.runNixOSTest (import ./nix/nixosTest.nix { inherit nixpkgs; });
|
nixosTest = pkgs.testers.runNixOSTest (import ./nix/nixosTest.nix { inherit nixpkgs; });
|
||||||
|
|||||||
+2
-3
@@ -9,11 +9,9 @@ CHECK_LOCAL = no-check-local
|
|||||||
|
|
||||||
AM_CPPFLAGS += -DHOST=\"$(CANONICAL_HOST)\"
|
AM_CPPFLAGS += -DHOST=\"$(CANONICAL_HOST)\"
|
||||||
|
|
||||||
include_HEADERS = heim_threads.h
|
|
||||||
|
|
||||||
nodist_include_HEADERS = krb5-types.h
|
nodist_include_HEADERS = krb5-types.h
|
||||||
|
|
||||||
noinst_HEADERS = heimqueue.h crypto-headers.h
|
noinst_HEADERS = heimqueue.h heim_threads.h crypto-headers.h
|
||||||
|
|
||||||
EXTRA_DIST = NTMakefile krb5-types.cross config.h.w32
|
EXTRA_DIST = NTMakefile krb5-types.cross config.h.w32
|
||||||
|
|
||||||
@@ -50,6 +48,7 @@ CLEANFILES = \
|
|||||||
der.h \
|
der.h \
|
||||||
digest_asn1.h \
|
digest_asn1.h \
|
||||||
digest_template_asn1.h \
|
digest_template_asn1.h \
|
||||||
|
editline.h \
|
||||||
err.h \
|
err.h \
|
||||||
getarg.h \
|
getarg.h \
|
||||||
glob.h \
|
glob.h \
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ kadmind_SOURCES = \
|
|||||||
|
|
||||||
add_random_users_SOURCES = add-random-users.c
|
add_random_users_SOURCES = add-random-users.c
|
||||||
|
|
||||||
test_util_SOURCES = test_util.c util.c random_password.c
|
test_util_SOURCES = test_util.c util.c
|
||||||
|
|
||||||
TESTS = test_util
|
TESTS = test_util
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,12 @@ do_ext_keytab(krb5_principal principal, void *data)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* Debug: record which principal was fetched and some context */
|
||||||
|
krb5_warnx(context, "do_ext_keytab: fetched principal %s mask=0x%x n_key_data=%d",
|
||||||
|
unparsed ? unparsed : "<unparsed>",
|
||||||
|
mask,
|
||||||
|
(int)princ.n_key_data);
|
||||||
|
|
||||||
if (!e->random_key_flag) {
|
if (!e->random_key_flag) {
|
||||||
if (princ.n_key_data == 0) {
|
if (princ.n_key_data == 0) {
|
||||||
krb5_warnx(context, "principal has no keys, or user lacks "
|
krb5_warnx(context, "principal has no keys, or user lacks "
|
||||||
@@ -111,6 +117,13 @@ do_ext_keytab(krb5_principal principal, void *data)
|
|||||||
keys[i].keyblock.keyvalue.data = kd->key_data_contents[0];
|
keys[i].keyblock.keyvalue.data = kd->key_data_contents[0];
|
||||||
keys[i].timestamp = time(NULL);
|
keys[i].timestamp = time(NULL);
|
||||||
n_k++;
|
n_k++;
|
||||||
|
|
||||||
|
/* Debug: log each key extracted (kvno/enctype) for the principal */
|
||||||
|
krb5_warnx(context, "do_ext_keytab: principal=%s key_index=%zu kvno=%d enctype=%d",
|
||||||
|
unparsed ? unparsed : "<unparsed>",
|
||||||
|
i,
|
||||||
|
keys[i].vno,
|
||||||
|
keys[i].keyblock.keytype);
|
||||||
}
|
}
|
||||||
} else if (e->random_key_flag) {
|
} else if (e->random_key_flag) {
|
||||||
ret = kadm5_randkey_principal_3(e->kadm_handle, principal, e->keep,
|
ret = kadm5_randkey_principal_3(e->kadm_handle, principal, e->keep,
|
||||||
@@ -208,6 +221,10 @@ ext_keytab(struct ext_keytab_options *opt, int argc, char **argv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Debug: record ext_keytab invocation details */
|
||||||
|
krb5_warnx(context, "ext_keytab: invoking foreach_principal for %zu principals, enctypes=%s",
|
||||||
|
(size_t)argc, enctypes ? enctypes : "<none>");
|
||||||
|
|
||||||
for(i = 0; i < argc; i++) {
|
for(i = 0; i < argc; i++) {
|
||||||
ret = foreach_principal(argv[i], do_ext_keytab, "ext", &data);
|
ret = foreach_principal(argv[i], do_ext_keytab, "ext", &data);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|||||||
+69
-4
@@ -488,12 +488,71 @@ do_get_entry(krb5_principal principal, void *data)
|
|||||||
e->upto--;
|
e->upto--;
|
||||||
|
|
||||||
memset(&princ, 0, sizeof(princ));
|
memset(&princ, 0, sizeof(princ));
|
||||||
ret = kadm5_get_principal(e->kadm_handle, principal,
|
|
||||||
&princ,
|
/* Loud tracing: record which principal we are about to request from kadmind.
|
||||||
e->mask | e->extra_mask);
|
*
|
||||||
|
* Guard the unparse call: don't call into unparse with a NULL principal
|
||||||
|
* and only use the unparsed string if the call succeeds.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
char *want = NULL;
|
||||||
|
if (principal != NULL && krb5_unparse_name(context, principal, &want) == 0 && want != NULL) {
|
||||||
|
krb5_warnx(context, "kadmin:get: do_get_entry: requesting principal lookup for %s (mask=0x%x extra_mask=0x%x) (pid=%d)",
|
||||||
|
want, e->mask, e->extra_mask, (int)getpid());
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "kadmin:get: do_get_entry: requesting principal lookup for <unparsed> (mask=0x%x extra_mask=0x%x) (pid=%d)",
|
||||||
|
e->mask, e->extra_mask, (int)getpid());
|
||||||
|
}
|
||||||
|
free(want);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Always request the principal field so we can safely unparse/format
|
||||||
|
* the returned entry. Some callers request only TL_DATA (eg aliases),
|
||||||
|
* and the kadm5 backend may return successful results without filling
|
||||||
|
* the principal pointer which leads to crashes when we try to use it.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
uint32_t want_mask = e->mask | e->extra_mask | KADM5_PRINCIPAL;
|
||||||
|
ret = kadm5_get_principal(e->kadm_handle, principal,
|
||||||
|
&princ,
|
||||||
|
want_mask);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
/* Success: log the fact we received a principal record and some basic info */
|
||||||
|
{
|
||||||
|
char *got = NULL;
|
||||||
|
if (krb5_unparse_name(context, princ.principal, &got) == 0) {
|
||||||
|
krb5_warnx(context, "kadmin:get: do_get_entry: kadm5_get_principal succeeded: principal=%s kvno=%d n_key_data=%d (pid=%d)",
|
||||||
|
got ? got : "<unparsed>",
|
||||||
|
princ.kvno,
|
||||||
|
princ.n_key_data,
|
||||||
|
(int)getpid());
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "kadmin:get: do_get_entry: kadm5_get_principal succeeded: <unparsed principal> kvno=%d n_key_data=%d (pid=%d)",
|
||||||
|
princ.kvno, princ.n_key_data, (int)getpid());
|
||||||
|
}
|
||||||
|
free(got);
|
||||||
|
}
|
||||||
|
|
||||||
(e->format)(e, &princ);
|
(e->format)(e, &princ);
|
||||||
kadm5_free_principal_ent(e->kadm_handle, &princ);
|
kadm5_free_principal_ent(e->kadm_handle, &princ);
|
||||||
|
} else {
|
||||||
|
/* Failure: log explicit error so we can trace failing lookups.
|
||||||
|
*
|
||||||
|
* Guard the unparse call similarly to above.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
char *want2 = NULL;
|
||||||
|
if (principal != NULL && krb5_unparse_name(context, principal, &want2) == 0 && want2 != NULL) {
|
||||||
|
krb5_warn(context, ret, "kadmin:get: do_get_entry: kadm5_get_principal(%s) failed (pid=%d)",
|
||||||
|
want2, (int)getpid());
|
||||||
|
} else {
|
||||||
|
krb5_warn(context, ret, "kadmin:get: do_get_entry: kadm5_get_principal(<unparsed>) failed (pid=%d)",
|
||||||
|
(int)getpid());
|
||||||
|
}
|
||||||
|
free(want2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e->n++;
|
e->n++;
|
||||||
@@ -627,8 +686,14 @@ getit(struct get_options *opt, const char *name, int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < argc; i++)
|
for(i = 0; i < argc; i++) {
|
||||||
|
/* Loud tracing: announce each foreach_principal invocation */
|
||||||
|
krb5_warnx(context, "kadmin:get: getit: invoking foreach_principal for arg[%d]=%s (call %d of %d) (pid=%d)",
|
||||||
|
i, argv[i] ? argv[i] : "<null>", i+1, argc, (int)getpid());
|
||||||
ret = foreach_principal(argv[i], do_get_entry, name, &data);
|
ret = foreach_principal(argv[i], do_get_entry, name, &data);
|
||||||
|
if (ret)
|
||||||
|
krb5_warn(context, ret, "kadmin:get: getit: foreach_principal(%s) returned error", argv[i] ? argv[i] : "<null>");
|
||||||
|
}
|
||||||
|
|
||||||
kadm5_destroy(data.kadm_handle);
|
kadm5_destroy(data.kadm_handle);
|
||||||
|
|
||||||
|
|||||||
+120
-19
@@ -32,30 +32,131 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kadmin_locl.h"
|
#include "kadmin_locl.h"
|
||||||
#include <base64.h>
|
|
||||||
|
|
||||||
#define RANDOM_PASSWORD_BYTES 12
|
/* This file defines some a function that generates a random password,
|
||||||
|
that can be used when creating a large amount of principals (such
|
||||||
|
as for a batch of students). Since this is a political matter, you
|
||||||
|
should think about how secure generated passwords has to be.
|
||||||
|
|
||||||
|
Both methods defined here will give you at least 55 bits of
|
||||||
|
entropy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* If you want OTP-style passwords, define OTP_STYLE */
|
||||||
|
|
||||||
|
#ifdef OTP_STYLE
|
||||||
|
#include <otp.h>
|
||||||
|
#else
|
||||||
|
static void generate_password(char **pw, int num_classes, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
random_password(char *pw, size_t len)
|
random_password(char *pw, size_t len)
|
||||||
{
|
{
|
||||||
unsigned char random[RANDOM_PASSWORD_BYTES];
|
#ifdef OTP_STYLE
|
||||||
char *password = NULL;
|
{
|
||||||
size_t password_len;
|
OtpKey newkey;
|
||||||
|
|
||||||
if (len == 0)
|
krb5_generate_random_block(&newkey, sizeof(newkey));
|
||||||
return;
|
otp_print_stddict (newkey, pw, len);
|
||||||
|
strlwr(pw);
|
||||||
krb5_generate_random_block(random, sizeof(random));
|
|
||||||
if (rk_base64url_encode(random, sizeof(random), &password) < 0 ||
|
|
||||||
password == NULL) {
|
|
||||||
memset_s(random, sizeof(random), 0, sizeof(random));
|
|
||||||
krb5_abortx(NULL, "Failed to encode random password");
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
password_len = strlen(password);
|
char *pass;
|
||||||
strlcpy(pw, password, len);
|
generate_password(&pass, 3,
|
||||||
memset_s(random, sizeof(random), 0, sizeof(random));
|
"abcdefghijklmnopqrstuvwxyz", 7,
|
||||||
memset_s(password, password_len, 0, password_len);
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2,
|
||||||
free(password);
|
"@$%&*()-+=:,/<>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;
|
||||||
|
va_start(ap, num_classes);
|
||||||
|
len = 0;
|
||||||
|
for(i = 0; i < num_classes; i++){
|
||||||
|
classes[i].str = va_arg(ap, const char*);
|
||||||
|
classes[i].len = strlen(classes[i].str);
|
||||||
|
classes[i].freq = va_arg(ap, int);
|
||||||
|
len += classes[i].freq;
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
*pw = malloc(len + 1);
|
||||||
|
if(*pw == NULL) {
|
||||||
|
free(classes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(i = 0; i < len; i++) {
|
||||||
|
int j;
|
||||||
|
int x = RND(rbuf, sizeof(rbuf), &rleft) % (len - i);
|
||||||
|
int t = 0;
|
||||||
|
for(j = 0; j < num_classes; j++) {
|
||||||
|
if(x < t + classes[j].freq) {
|
||||||
|
(*pw)[i] = classes[j].str[RND(rbuf, sizeof(rbuf), &rleft)
|
||||||
|
% classes[j].len];
|
||||||
|
classes[j].freq--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t += classes[j].freq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*pw)[len] = '\0';
|
||||||
|
memset_s(rbuf, sizeof(rbuf), 0, sizeof(rbuf));
|
||||||
|
free(classes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -624,7 +624,31 @@ proc_get_principal(kadm5_server_context *contextp,
|
|||||||
if(ret)
|
if(ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
/* Loud tracing: log which client requested this GET and what principal is being looked up */
|
||||||
|
{
|
||||||
|
char *want = NULL;
|
||||||
|
(void) krb5_unparse_name(contextp->context, princ, &want);
|
||||||
|
krb5_warnx(contextp->context,
|
||||||
|
"proc_get_principal: received GET request for principal=%s mask=0x%x (pid=%d ppid=%d uid=%d)",
|
||||||
|
want ? want : "<unparsed>",
|
||||||
|
mask,
|
||||||
|
(int)getpid(),
|
||||||
|
(int)getppid(),
|
||||||
|
(int)getuid());
|
||||||
|
free(want);
|
||||||
|
}
|
||||||
|
|
||||||
ret = kadm5_get_principal(contextp, princ, &ent, mask);
|
ret = kadm5_get_principal(contextp, princ, &ent, mask);
|
||||||
|
if (ret) {
|
||||||
|
/* Extra log to make failures obvious at the call site */
|
||||||
|
char *want2 = NULL;
|
||||||
|
(void) krb5_unparse_name(contextp->context, princ, &want2);
|
||||||
|
krb5_warn(contextp->context, ret,
|
||||||
|
"proc_get_principal: kadm5_get_principal failed for principal=%s (pid=%d)",
|
||||||
|
want2 ? want2 : "<unparsed>",
|
||||||
|
(int)getpid());
|
||||||
|
free(want2);
|
||||||
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
krb5_warn(contextp->context, ret, "get principal principal");
|
krb5_warn(contextp->context, ret, "get principal principal");
|
||||||
|
|||||||
@@ -226,6 +226,8 @@ kadmind_dispatch_int(void *kadm_handlep, krb5_boolean initial,
|
|||||||
ret_sp = krb5_store_int32(rsp, KADM5_FAILURE);
|
ret_sp = krb5_store_int32(rsp, KADM5_FAILURE);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
/* Debug: record which client and numeric command we received */
|
||||||
|
krb5_warnx(contextp->context, "kadmind_dispatch: received request from client=%s cmd=%d", client, cmd);
|
||||||
|
|
||||||
switch(cmd){
|
switch(cmd){
|
||||||
case kadm_nop:{
|
case kadm_nop:{
|
||||||
@@ -268,6 +270,8 @@ kadmind_dispatch_int(void *kadm_handlep, krb5_boolean initial,
|
|||||||
mask |= KADM5_PRINCIPAL;
|
mask |= KADM5_PRINCIPAL;
|
||||||
krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name));
|
krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name));
|
||||||
krb5_warnx(contextp->context, "%s: %s %s", client, op, name);
|
krb5_warnx(contextp->context, "%s: %s %s", client, op, name);
|
||||||
|
/* Debug: include mask/keys_ok context so we can correlate admin requests to keytab lookups */
|
||||||
|
krb5_warnx(contextp->context, "kadmind_dispatch: GET invoked by %s for %s (mask=0x%x, keys_ok=%d)", client, name, mask, keys_ok);
|
||||||
|
|
||||||
/* If the caller doesn't have KADM5_PRIV_GET, we're done. */
|
/* If the caller doesn't have KADM5_PRIV_GET, we're done. */
|
||||||
ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_GET, princ);
|
ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_GET, princ);
|
||||||
@@ -307,6 +311,7 @@ kadmind_dispatch_int(void *kadm_handlep, krb5_boolean initial,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
krb5_warnx(contextp->context, "kadmind_dispatch: calling kadm5_get_principal for %s (mask=0x%x, keys_ok=%d)", name, mask, keys_ok);
|
||||||
ret = kadm5_get_principal(kadm_handlep, princ, &ent, mask);
|
ret = kadm5_get_principal(kadm_handlep, princ, &ent, mask);
|
||||||
ret_sp = krb5_store_int32(rsp, ret);
|
ret_sp = krb5_store_int32(rsp, ret);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
|||||||
+1
-44
@@ -68,49 +68,6 @@ test_time(void)
|
|||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
test_random_password(void)
|
|
||||||
{
|
|
||||||
static const char alphabet[] =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
||||||
char pw[128];
|
|
||||||
char small[5];
|
|
||||||
char zero[1] = { 'x' };
|
|
||||||
size_t i, j;
|
|
||||||
int errors = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 128; i++) {
|
|
||||||
random_password(pw, sizeof(pw));
|
|
||||||
if (strlen(pw) != 16) {
|
|
||||||
printf("wrong random password length: %lu\n",
|
|
||||||
(unsigned long)strlen(pw));
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
for (j = 0; pw[j] != '\0'; j++) {
|
|
||||||
if (strchr(alphabet, pw[j]) == NULL) {
|
|
||||||
printf("random password contains invalid byte: 0x%02x\n",
|
|
||||||
(unsigned char)pw[j]);
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
random_password(small, sizeof(small));
|
|
||||||
if (strlen(small) != sizeof(small) - 1) {
|
|
||||||
printf("wrong short random password length: %lu\n",
|
|
||||||
(unsigned long)strlen(small));
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
random_password(zero, 0);
|
|
||||||
if (zero[0] != 'x') {
|
|
||||||
printf("zero-length random password buffer was modified\n");
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
@@ -125,9 +82,9 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
ret += test_time();
|
ret += test_time();
|
||||||
ret += test_random_password();
|
|
||||||
|
|
||||||
krb5_free_context(context);
|
krb5_free_context(context);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-6
@@ -460,7 +460,6 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
char *armor_client_principal_name = NULL;
|
char *armor_client_principal_name = NULL;
|
||||||
char *armor_server_principal_name = NULL;
|
char *armor_server_principal_name = NULL;
|
||||||
PA_FX_FAST_REQUEST fxreq;
|
PA_FX_FAST_REQUEST fxreq;
|
||||||
krb5_auth_context free_ac = NULL;
|
|
||||||
krb5_auth_context ac = NULL;
|
krb5_auth_context ac = NULL;
|
||||||
krb5_ticket *ticket = NULL;
|
krb5_ticket *ticket = NULL;
|
||||||
krb5_flags ap_req_options;
|
krb5_flags ap_req_options;
|
||||||
@@ -582,7 +581,7 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_verify_ap_req2(r->context, &free_ac,
|
ret = krb5_verify_ap_req2(r->context, &ac,
|
||||||
&ap_req,
|
&ap_req,
|
||||||
armor_server_principal,
|
armor_server_principal,
|
||||||
&r->armor_key->key,
|
&r->armor_key->key,
|
||||||
@@ -594,8 +593,6 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ac = free_ac;
|
|
||||||
|
|
||||||
ret = krb5_unparse_name(r->context, armor_server_principal,
|
ret = krb5_unparse_name(r->context, armor_server_principal,
|
||||||
&armor_server_principal_name);
|
&armor_server_principal_name);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -624,6 +621,7 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
"<out of memory>");
|
"<out of memory>");
|
||||||
|
|
||||||
if (ac->remote_subkey == NULL) {
|
if (ac->remote_subkey == NULL) {
|
||||||
|
krb5_auth_con_free(r->context, ac);
|
||||||
kdc_log(r->context, r->config, 2,
|
kdc_log(r->context, r->config, 2,
|
||||||
"FAST AP-REQ remote subkey missing");
|
"FAST AP-REQ remote subkey missing");
|
||||||
ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||||
@@ -749,8 +747,8 @@ fast_unwrap_request(astgs_request_t r,
|
|||||||
kdc_log(r->context, r->config, 5, "Client selected FAST");
|
kdc_log(r->context, r->config, 5, "Client selected FAST");
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (free_ac)
|
if (ac && ac != tgs_ac)
|
||||||
krb5_auth_con_free(r->context, free_ac);
|
krb5_auth_con_free(r->context, ac);
|
||||||
|
|
||||||
krb5_free_principal(r->context, armor_server_principal);
|
krb5_free_principal(r->context, armor_server_principal);
|
||||||
krb5_xfree(armor_client_principal_name);
|
krb5_xfree(armor_client_principal_name);
|
||||||
|
|||||||
+1
-28
@@ -51,7 +51,7 @@ static const char *kdc_plugin_deps[] = {
|
|||||||
static struct heim_plugin_data kdc_plugin_data = {
|
static struct heim_plugin_data kdc_plugin_data = {
|
||||||
"krb5",
|
"krb5",
|
||||||
"kdc",
|
"kdc",
|
||||||
KRB5_PLUGIN_KDC_VERSION_11,
|
KRB5_PLUGIN_KDC_VERSION_10,
|
||||||
kdc_plugin_deps,
|
kdc_plugin_deps,
|
||||||
kdc_get_instance
|
kdc_get_instance
|
||||||
};
|
};
|
||||||
@@ -239,33 +239,6 @@ _kdc_referral_policy(astgs_request_t r)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code KRB5_LIB_CALL
|
|
||||||
hwauth_policy(krb5_context context, const void *plug, void *plugctx, void *userctx)
|
|
||||||
{
|
|
||||||
const krb5plugin_kdc_ftable *ft = plug;
|
|
||||||
|
|
||||||
if (ft->hwauth_policy == NULL) {
|
|
||||||
return KRB5_PLUGIN_NO_HANDLE;
|
|
||||||
}
|
|
||||||
return ft->hwauth_policy(rk_UNCONST(plug), userctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
krb5_error_code
|
|
||||||
_kdc_hwauth_policy(astgs_request_t r)
|
|
||||||
{
|
|
||||||
krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
|
|
||||||
|
|
||||||
if (have_plugin) {
|
|
||||||
ret = _krb5_plugin_run_f(r->context, &kdc_plugin_data, 0, r, hwauth_policy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != KRB5_PLUGIN_NO_HANDLE) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r->client->flags.require_hwauth ? KRB5KDC_ERR_POLICY : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static krb5_error_code KRB5_LIB_CALL
|
static krb5_error_code KRB5_LIB_CALL
|
||||||
finalize_reply(krb5_context context, const void *plug, void *plugctx, void *userctx)
|
finalize_reply(krb5_context context, const void *plug, void *plugctx, void *userctx)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-12
@@ -95,16 +95,6 @@ typedef krb5_error_code
|
|||||||
typedef krb5_error_code
|
typedef krb5_error_code
|
||||||
(KRB5_CALLCONV *krb5plugin_kdc_referral_policy)(void *, astgs_request_t);
|
(KRB5_CALLCONV *krb5plugin_kdc_referral_policy)(void *, astgs_request_t);
|
||||||
|
|
||||||
/*
|
|
||||||
* A hardware authentication policy plugin can indicate what is to
|
|
||||||
* happen when a client authenticates using a method other than
|
|
||||||
* hardware authentication. It can return zero to allow the
|
|
||||||
* authentication, or an appropriate error code to deny it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef krb5_error_code
|
|
||||||
(KRB5_CALLCONV *krb5plugin_kdc_hwauth_policy)(void *, astgs_request_t);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the AS or TGS reply immediately prior to encoding.
|
* Update the AS or TGS reply immediately prior to encoding.
|
||||||
*/
|
*/
|
||||||
@@ -127,7 +117,7 @@ typedef krb5_error_code
|
|||||||
* Plugins should carefully check API contract notes for changes
|
* Plugins should carefully check API contract notes for changes
|
||||||
* between plugin API versions.
|
* between plugin API versions.
|
||||||
*/
|
*/
|
||||||
#define KRB5_PLUGIN_KDC_VERSION_11 11
|
#define KRB5_PLUGIN_KDC_VERSION_10 10
|
||||||
|
|
||||||
typedef struct krb5plugin_kdc_ftable {
|
typedef struct krb5plugin_kdc_ftable {
|
||||||
HEIM_PLUGIN_FTABLE_COMMON_ELEMENTS(krb5_context);
|
HEIM_PLUGIN_FTABLE_COMMON_ELEMENTS(krb5_context);
|
||||||
@@ -135,7 +125,6 @@ typedef struct krb5plugin_kdc_ftable {
|
|||||||
krb5plugin_kdc_pac_verify pac_verify;
|
krb5plugin_kdc_pac_verify pac_verify;
|
||||||
krb5plugin_kdc_client_access client_access;
|
krb5plugin_kdc_client_access client_access;
|
||||||
krb5plugin_kdc_referral_policy referral_policy;
|
krb5plugin_kdc_referral_policy referral_policy;
|
||||||
krb5plugin_kdc_hwauth_policy hwauth_policy;
|
|
||||||
krb5plugin_kdc_finalize_reply finalize_reply;
|
krb5plugin_kdc_finalize_reply finalize_reply;
|
||||||
krb5plugin_kdc_audit audit;
|
krb5plugin_kdc_audit audit;
|
||||||
} krb5plugin_kdc_ftable;
|
} krb5plugin_kdc_ftable;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
+13
-19
@@ -37,15 +37,16 @@
|
|||||||
#if SIZEOF_TIME_T == 4
|
#if SIZEOF_TIME_T == 4
|
||||||
#define MAX_TIME ((time_t)INT32_MAX)
|
#define MAX_TIME ((time_t)INT32_MAX)
|
||||||
#elif SIZEOF_TIME_T == 8
|
#elif SIZEOF_TIME_T == 8
|
||||||
#define MAX_TIME ((time_t)INT64_MAX)
|
#define MAX_TIME ((time_t)INT32_MAX)
|
||||||
#else
|
#else
|
||||||
#error "Unexpected sizeof(time_t)"
|
#error "Unexpected sizeof(time_t)"
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if SIZEOF_TIME_T == 4
|
#if SIZEOF_TIME_T == 4
|
||||||
#define MAX_TIME ((time_t)UINT32_MAX)
|
#define MAX_TIME ((time_t)INT32_MAX)
|
||||||
#else
|
#else
|
||||||
#define MAX_TIME ((time_t)UINT64_MAX)
|
#define MAX_TIME ((time_t)INT32_MAX)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -535,11 +536,7 @@ pa_pkinit_validate(astgs_request_t r, const PA_DATA *pa)
|
|||||||
|
|
||||||
ret = _kdc_pk_rd_padata(r, pa, &pkp);
|
ret = _kdc_pk_rd_padata(r, pa, &pkp);
|
||||||
if (ret || pkp == NULL) {
|
if (ret || pkp == NULL) {
|
||||||
if (ret == KRB5_KDC_ERR_REVOKED_CERTIFICATE) {
|
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
|
||||||
ret = KRB5_KDC_ERR_CLIENT_NOT_TRUSTED;
|
|
||||||
} else {
|
|
||||||
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
|
|
||||||
}
|
|
||||||
_kdc_r_log(r, 4, "Failed to decode PKINIT PA-DATA -- %s",
|
_kdc_r_log(r, 4, "Failed to decode PKINIT PA-DATA -- %s",
|
||||||
r->cname);
|
r->cname);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -938,9 +935,6 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
free_EncryptedData(&enc_data);
|
free_EncryptedData(&enc_data);
|
||||||
if (ret) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = decode_PA_ENC_TS_ENC(ts_data.data,
|
ret = decode_PA_ENC_TS_ENC(ts_data.data,
|
||||||
ts_data.length,
|
ts_data.length,
|
||||||
&p,
|
&p,
|
||||||
@@ -952,7 +946,7 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
|
|||||||
r->cname);
|
r->cname);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (krb5_time_abs(kdc_time, p.patimestamp) > r->context->max_skew) {
|
if (labs(kdc_time - p.patimestamp) > r->context->max_skew) {
|
||||||
char client_time[100];
|
char client_time[100];
|
||||||
|
|
||||||
krb5_format_time(r->context, p.patimestamp,
|
krb5_format_time(r->context, p.patimestamp,
|
||||||
@@ -962,7 +956,7 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
|
|||||||
_kdc_r_log(r, 4, "Too large time skew, "
|
_kdc_r_log(r, 4, "Too large time skew, "
|
||||||
"client time %s is out by %u > %u seconds -- %s",
|
"client time %s is out by %u > %u seconds -- %s",
|
||||||
client_time,
|
client_time,
|
||||||
(unsigned)krb5_time_abs(kdc_time, p.patimestamp),
|
(unsigned)labs(kdc_time - p.patimestamp),
|
||||||
r->context->max_skew,
|
r->context->max_skew,
|
||||||
r->cname);
|
r->cname);
|
||||||
kdc_audit_setkv_number((kdc_request_t)r, KDC_REQUEST_KV_AUTH_EVENT,
|
kdc_audit_setkv_number((kdc_request_t)r, KDC_REQUEST_KV_AUTH_EVENT,
|
||||||
@@ -2269,12 +2263,12 @@ _kdc_as_rep(astgs_request_t r)
|
|||||||
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
|
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!(pat[n].flags & PA_HARDWARE_AUTH)) {
|
if (r->client->flags.require_hwauth &&
|
||||||
ret = _kdc_hwauth_policy(r);
|
!(pat[n].flags & PA_HARDWARE_AUTH)) {
|
||||||
if (ret) {
|
kdc_log(r->context, config, 4, "Hardware authentication required for %s", r->cname);
|
||||||
kdc_log(r->context, config, 4, "Hardware authentication required for %s", r->cname);
|
|
||||||
goto out;
|
ret = KRB5KDC_ERR_POLICY;
|
||||||
}
|
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);
|
||||||
|
|||||||
+19
-12
@@ -399,6 +399,7 @@ mk_error_response(krb5_context context,
|
|||||||
Kx509Response rep;
|
Kx509Response rep;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
char *freeme0 = NULL;
|
char *freeme0 = NULL;
|
||||||
|
char *freeme1 = NULL;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
@@ -416,6 +417,9 @@ mk_error_response(krb5_context context,
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!reqctx->config->enable_kx509)
|
||||||
|
code = KRB5KDC_ERR_POLICY;
|
||||||
|
|
||||||
/* Make sure we only send RFC4120 and friends wire protocol error codes */
|
/* Make sure we only send RFC4120 and friends wire protocol error codes */
|
||||||
if (code) {
|
if (code) {
|
||||||
if (code == KX509_ERR_NONE) {
|
if (code == KX509_ERR_NONE) {
|
||||||
@@ -437,6 +441,12 @@ mk_error_response(krb5_context context,
|
|||||||
msg = freeme0;
|
msg = freeme0;
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
|
if (!reqctx->config->enable_kx509 &&
|
||||||
|
asprintf(&freeme1, "kx509 service is disabled (%s)", msg) > -1 &&
|
||||||
|
freeme1 != NULL) {
|
||||||
|
msg = freeme1;
|
||||||
|
}
|
||||||
|
|
||||||
rep.hash = NULL;
|
rep.hash = NULL;
|
||||||
rep.certificate = NULL;
|
rep.certificate = NULL;
|
||||||
rep.error_code = code;
|
rep.error_code = code;
|
||||||
@@ -458,6 +468,7 @@ mk_error_response(krb5_context context,
|
|||||||
free(rep.e_text);
|
free(rep.e_text);
|
||||||
free(rep.hash);
|
free(rep.hash);
|
||||||
free(freeme0);
|
free(freeme0);
|
||||||
|
free(freeme1);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -889,15 +900,14 @@ _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, 0,
|
||||||
ret = mk_error_response(r->context, r, 4, KRB5KDC_ERR_POLICY,
|
"kx509 service is available");
|
||||||
"kx509 service is disabled");
|
|
||||||
else
|
|
||||||
ret = mk_error_response(r->context, r, 4, 0,
|
|
||||||
"kx509 service is available");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -928,12 +938,6 @@ _kdc_do_kx509(kx509_req_context r)
|
|||||||
* Provided we got the session key, errors past this point will be
|
* Provided we got the session key, errors past this point will be
|
||||||
* authenticated.
|
* authenticated.
|
||||||
*/
|
*/
|
||||||
if (ret == 0 && !r->config->enable_kx509) {
|
|
||||||
ret = mk_error_response(r->context, r, 4, KRB5KDC_ERR_POLICY,
|
|
||||||
"kx509 service is disabled");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = krb5_ticket_get_client(r->context, ticket, &cprincipal);
|
ret = krb5_ticket_get_client(r->context, ticket, &cprincipal);
|
||||||
|
|
||||||
@@ -979,6 +983,9 @@ _kdc_do_kx509(kx509_req_context r)
|
|||||||
if (r->req.pk_key.length == 0) {
|
if (r->req.pk_key.length == 0) {
|
||||||
/*
|
/*
|
||||||
* The request is an authenticated kx509 service availability probe.
|
* The request is an authenticated kx509 service availability probe.
|
||||||
|
*
|
||||||
|
* mk_error_response() will check whether the service is enabled and
|
||||||
|
* possibly change the error code and message.
|
||||||
*/
|
*/
|
||||||
is_probe = 1;
|
is_probe = 1;
|
||||||
kdc_audit_addkv((kdc_request_t)r, 0, "probe", "authenticated");
|
kdc_audit_addkv((kdc_request_t)r, 0, "probe", "authenticated");
|
||||||
|
|||||||
+2
-4
@@ -432,7 +432,7 @@ pk_check_pkauthenticator_win2k(krb5_context context,
|
|||||||
krb5_timeofday (context, &now);
|
krb5_timeofday (context, &now);
|
||||||
|
|
||||||
/* XXX cusec */
|
/* XXX cusec */
|
||||||
if (a->ctime == 0 || krb5_time_abs(a->ctime, now) > context->max_skew) {
|
if (a->ctime == 0 || labs(a->ctime - now) > context->max_skew) {
|
||||||
krb5_clear_error_message(context);
|
krb5_clear_error_message(context);
|
||||||
return KRB5KRB_AP_ERR_SKEW;
|
return KRB5KRB_AP_ERR_SKEW;
|
||||||
}
|
}
|
||||||
@@ -451,7 +451,7 @@ pk_check_pkauthenticator(krb5_context context,
|
|||||||
krb5_timeofday (context, &now);
|
krb5_timeofday (context, &now);
|
||||||
|
|
||||||
/* XXX cusec */
|
/* XXX cusec */
|
||||||
if (a->ctime == 0 || krb5_time_abs(a->ctime, now) > context->max_skew) {
|
if (a->ctime == 0 || labs(a->ctime - now) > context->max_skew) {
|
||||||
krb5_clear_error_message(context);
|
krb5_clear_error_message(context);
|
||||||
return KRB5KRB_AP_ERR_SKEW;
|
return KRB5KRB_AP_ERR_SKEW;
|
||||||
}
|
}
|
||||||
@@ -797,8 +797,6 @@ _kdc_pk_rd_padata(astgs_request_t priv,
|
|||||||
hx509_verify_attach_anchors(cp->verify_ctx, trust_anchors);
|
hx509_verify_attach_anchors(cp->verify_ctx, trust_anchors);
|
||||||
hx509_certs_free(&trust_anchors);
|
hx509_certs_free(&trust_anchors);
|
||||||
|
|
||||||
hx509_verify_attach_revoke(cp->verify_ctx, kdc_identity->revokectx);
|
|
||||||
|
|
||||||
if (config->pkinit_allow_proxy_certs)
|
if (config->pkinit_allow_proxy_certs)
|
||||||
hx509_verify_set_proxy_certificate(cp->verify_ctx, 1);
|
hx509_verify_set_proxy_certificate(cp->verify_ctx, 1);
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -1104,8 +1104,7 @@ get_new_tickets(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ticket_life != 0) {
|
if (ticket_life != 0) {
|
||||||
if (krb5_time_abs(cred.times.endtime - cred.times.starttime,
|
if (labs(cred.times.endtime - cred.times.starttime - ticket_life) > 30) {
|
||||||
ticket_life) > 30) {
|
|
||||||
char life[64];
|
char life[64];
|
||||||
unparse_time_approx(cred.times.endtime - cred.times.starttime,
|
unparse_time_approx(cred.times.endtime - cred.times.starttime,
|
||||||
life, sizeof(life));
|
life, sizeof(life));
|
||||||
@@ -1113,8 +1112,7 @@ get_new_tickets(krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (renew_life) {
|
if (renew_life) {
|
||||||
if (krb5_time_abs(cred.times.renew_till - cred.times.starttime,
|
if (labs(cred.times.renew_till - cred.times.starttime - renew) > 30) {
|
||||||
renew) > 30) {
|
|
||||||
char life[64];
|
char life[64];
|
||||||
unparse_time_approx(cred.times.renew_till - cred.times.starttime,
|
unparse_time_approx(cred.times.renew_till - cred.times.starttime,
|
||||||
life, sizeof(life));
|
life, sizeof(life));
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
include $(top_srcdir)/Makefile.am.common
|
include $(top_srcdir)/Makefile.am.common
|
||||||
|
|
||||||
|
if LIBEDIT
|
||||||
|
dir_editline = libedit
|
||||||
|
endif
|
||||||
if DCE
|
if DCE
|
||||||
dir_dce = kdfs
|
dir_dce = kdfs
|
||||||
endif
|
endif
|
||||||
@@ -18,6 +21,7 @@ SUBDIRS = \
|
|||||||
vers \
|
vers \
|
||||||
$(dir_com_err) \
|
$(dir_com_err) \
|
||||||
base \
|
base \
|
||||||
|
$(dir_editline) \
|
||||||
sl \
|
sl \
|
||||||
wind \
|
wind \
|
||||||
asn1 \
|
asn1 \
|
||||||
|
|||||||
@@ -97,10 +97,8 @@ der_print_hex_heim_integer (const heim_integer *data, char **p)
|
|||||||
if (data->negative) {
|
if (data->negative) {
|
||||||
len = asprintf(&q, "-%s", *p);
|
len = asprintf(&q, "-%s", *p);
|
||||||
free(*p);
|
free(*p);
|
||||||
if (len < 0) {
|
if (len < 0)
|
||||||
*p = NULL;
|
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
|
||||||
*p = q;
|
*p = q;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -191,7 +191,6 @@ init_generate (const char *filename, const char *base)
|
|||||||
fprintf (headerfile,
|
fprintf (headerfile,
|
||||||
"#include <stddef.h>\n"
|
"#include <stddef.h>\n"
|
||||||
"#include <stdint.h>\n"
|
"#include <stdint.h>\n"
|
||||||
"#include <errno.h>\n"
|
|
||||||
"#include <time.h>\n\n");
|
"#include <time.h>\n\n");
|
||||||
fprintf (headerfile,
|
fprintf (headerfile,
|
||||||
"#ifndef __asn1_common_definitions__\n"
|
"#ifndef __asn1_common_definitions__\n"
|
||||||
@@ -600,8 +599,6 @@ generate_constant (const Symbol *s)
|
|||||||
/* header file */
|
/* header file */
|
||||||
|
|
||||||
gen_upper = strdup(s->gen_name);
|
gen_upper = strdup(s->gen_name);
|
||||||
if (gen_upper == NULL)
|
|
||||||
errx(1, "malloc");
|
|
||||||
len = strlen(gen_upper);
|
len = strlen(gen_upper);
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
gen_upper[i] = toupper((unsigned char)s->gen_name[i]);
|
gen_upper[i] = toupper((unsigned char)s->gen_name[i]);
|
||||||
|
|||||||
@@ -289,11 +289,7 @@ static struct tlist *
|
|||||||
tlist_new(const char *name)
|
tlist_new(const char *name)
|
||||||
{
|
{
|
||||||
struct tlist *tl = calloc(1, sizeof(*tl));
|
struct tlist *tl = calloc(1, sizeof(*tl));
|
||||||
if (tl == NULL)
|
|
||||||
errx(1, "malloc");
|
|
||||||
tl->name = strdup(name);
|
tl->name = strdup(name);
|
||||||
if (tl->name == NULL)
|
|
||||||
errx(1, "malloc");
|
|
||||||
HEIM_TAILQ_INIT(&tl->template);
|
HEIM_TAILQ_INIT(&tl->template);
|
||||||
return tl;
|
return tl;
|
||||||
}
|
}
|
||||||
@@ -425,8 +421,6 @@ add_line(struct templatehead *t, const char *fmt, ...)
|
|||||||
{
|
{
|
||||||
struct template *q = calloc(1, sizeof(*q));
|
struct template *q = calloc(1, sizeof(*q));
|
||||||
va_list ap;
|
va_list ap;
|
||||||
if (q == NULL)
|
|
||||||
errx(1, "malloc");
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
if (vasprintf(&q->line, fmt, ap) < 0 || q->line == NULL)
|
if (vasprintf(&q->line, fmt, ap) < 0 || q->line == NULL)
|
||||||
errx(1, "malloc");
|
errx(1, "malloc");
|
||||||
|
|||||||
+14
-22
@@ -38,26 +38,12 @@
|
|||||||
#include <vis.h>
|
#include <vis.h>
|
||||||
#include <vis-extras.h>
|
#include <vis-extras.h>
|
||||||
#include <heimbase.h>
|
#include <heimbase.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#ifndef ENOTSUP
|
#ifndef ENOTSUP
|
||||||
/* Very old MSVC CRTs don't have ENOTSUP */
|
/* Very old MSVC CRTs don't have ENOTSUP */
|
||||||
#define ENOTSUP EINVAL
|
#define ENOTSUP EINVAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
|
||||||
int32_ptr_equal(int32_t i, const void *ptr)
|
|
||||||
{
|
|
||||||
const intptr_t v = (intptr_t)ptr;
|
|
||||||
|
|
||||||
#if INTPTR_MAX > INT32_MAX || INTPTR_MIN < INT32_MIN
|
|
||||||
if (v > INT32_MAX || v < INT32_MIN)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return i == (int32_t)v;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
|
struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
|
||||||
#define el(name, type) { \
|
#define el(name, type) { \
|
||||||
(asn1_type_encode)der_put_##name, \
|
(asn1_type_encode)der_put_##name, \
|
||||||
@@ -1507,7 +1493,9 @@ _asn1_encode(const struct asn1_template *t, unsigned char *p, size_t len, const
|
|||||||
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
||||||
const int32_t *i = el;
|
const int32_t *i = el;
|
||||||
|
|
||||||
if (int32_ptr_equal(*i, tdefval->ptr))
|
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
||||||
|
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
|
||||||
|
*i == (int32_t)(intptr_t)tdefval->ptr)
|
||||||
break;
|
break;
|
||||||
} else if (tdefval->tt & A1_DV_INTEGER) {
|
} else if (tdefval->tt & A1_DV_INTEGER) {
|
||||||
const struct heim_integer *i = el;
|
const struct heim_integer *i = el;
|
||||||
@@ -1579,7 +1567,9 @@ _asn1_encode(const struct asn1_template *t, unsigned char *p, size_t len, const
|
|||||||
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
||||||
const int32_t *i = data;
|
const int32_t *i = data;
|
||||||
|
|
||||||
if (int32_ptr_equal(*i, tdefval->ptr))
|
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
||||||
|
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
|
||||||
|
*i == (int32_t)(intptr_t)tdefval->ptr)
|
||||||
exclude = 1;
|
exclude = 1;
|
||||||
} else if (tdefval->tt & A1_DV_INTEGER) {
|
} else if (tdefval->tt & A1_DV_INTEGER) {
|
||||||
const struct heim_integer *i = data;
|
const struct heim_integer *i = data;
|
||||||
@@ -2082,7 +2072,9 @@ _asn1_length(const struct asn1_template *t, const void *data)
|
|||||||
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
||||||
const int32_t *i = el;
|
const int32_t *i = el;
|
||||||
|
|
||||||
if (int32_ptr_equal(*i, tdefval->ptr))
|
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
||||||
|
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
|
||||||
|
*i == (int32_t)(intptr_t)tdefval->ptr)
|
||||||
break;
|
break;
|
||||||
} else if (tdefval->tt & A1_DV_INTEGER) {
|
} else if (tdefval->tt & A1_DV_INTEGER) {
|
||||||
const struct heim_integer *i = el;
|
const struct heim_integer *i = el;
|
||||||
@@ -2139,7 +2131,9 @@ _asn1_length(const struct asn1_template *t, const void *data)
|
|||||||
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
} else if (tdefval->tt & A1_DV_INTEGER32) {
|
||||||
const int32_t *i = data;
|
const int32_t *i = data;
|
||||||
|
|
||||||
if (int32_ptr_equal(*i, tdefval->ptr))
|
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
|
||||||
|
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
|
||||||
|
*i == (int32_t)(intptr_t)tdefval->ptr)
|
||||||
exclude = 1;
|
exclude = 1;
|
||||||
} else if (tdefval->tt & A1_DV_INTEGER) {
|
} else if (tdefval->tt & A1_DV_INTEGER) {
|
||||||
const struct heim_integer *i = data;
|
const struct heim_integer *i = data;
|
||||||
@@ -2489,10 +2483,8 @@ _asn1_print_open_type(const struct asn1_template *t, /* object set template */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
||||||
size_t offset = t->offset + sizeof(*elementp);
|
unsigned align = 8 - ((t->offset + sizeof(*elementp)) & 0x7);
|
||||||
|
dp = DPOC(data, t->offset + sizeof(*elementp) + align);
|
||||||
offset += (sizeof(void *) - offset % sizeof(void *)) % sizeof(void *);
|
|
||||||
dp = DPOC(data, offset);
|
|
||||||
if (*dp) {
|
if (*dp) {
|
||||||
struct rk_strpool *r2 = NULL;
|
struct rk_strpool *r2 = NULL;
|
||||||
char *s = NULL;
|
char *s = NULL;
|
||||||
|
|||||||
+2
-17
@@ -46,21 +46,6 @@ static const unsigned ndays[2][12] ={
|
|||||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
||||||
|
|
||||||
static time_t
|
|
||||||
_clamp_time_t(uint64_t t)
|
|
||||||
{
|
|
||||||
#if SIZEOF_TIME_T < 8
|
|
||||||
#ifdef TIME_T_UNSIGNED
|
|
||||||
#define MAX_TIME ((UINT64_C(1) << (SIZEOF_TIME_T * 8)) - 1)
|
|
||||||
#else
|
|
||||||
#define MAX_TIME ((UINT64_C(1) << ((SIZEOF_TIME_T * 8) - 1)) - 1)
|
|
||||||
#endif
|
|
||||||
return t < MAX_TIME ? t : MAX_TIME;
|
|
||||||
#else
|
|
||||||
return t;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a simplifed version of timegm(3) that doesn't accept out of
|
* This is a simplifed version of timegm(3) that doesn't accept out of
|
||||||
* bound values that timegm(3) normally accepts but those are not
|
* bound values that timegm(3) normally accepts but those are not
|
||||||
@@ -70,7 +55,7 @@ _clamp_time_t(uint64_t t)
|
|||||||
time_t
|
time_t
|
||||||
_der_timegm (struct tm *tm)
|
_der_timegm (struct tm *tm)
|
||||||
{
|
{
|
||||||
uint64_t res = 0;
|
time_t res = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -104,7 +89,7 @@ _der_timegm (struct tm *tm)
|
|||||||
res += tm->tm_min;
|
res += tm->tm_min;
|
||||||
res *= 60;
|
res *= 60;
|
||||||
res += tm->tm_sec;
|
res += tm->tm_sec;
|
||||||
return _clamp_time_t(res);
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tm *
|
struct tm *
|
||||||
|
|||||||
+3
-23
@@ -86,26 +86,6 @@ static heim_error_code parse_list(struct fileptr *f, unsigned *lineno,
|
|||||||
heim_config_binding **parent,
|
heim_config_binding **parent,
|
||||||
const char **err_message);
|
const char **err_message);
|
||||||
|
|
||||||
static int
|
|
||||||
todash(int c)
|
|
||||||
{
|
|
||||||
if (c == '_')
|
|
||||||
return '-';
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
strcmp_du(const char *s1, const char *s2)
|
|
||||||
{
|
|
||||||
while (todash((unsigned char)*s1) == todash((unsigned char)*s2)) {
|
|
||||||
if (*s1 == '\0')
|
|
||||||
return 0;
|
|
||||||
s1++;
|
|
||||||
s2++;
|
|
||||||
}
|
|
||||||
return todash((unsigned char)*s1) - todash((unsigned char)*s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
heim_config_section *
|
heim_config_section *
|
||||||
heim_config_get_entry(heim_config_section **parent, const char *name, int type)
|
heim_config_get_entry(heim_config_section **parent, const char *name, int type)
|
||||||
{
|
{
|
||||||
@@ -114,7 +94,7 @@ heim_config_get_entry(heim_config_section **parent, const char *name, int type)
|
|||||||
for (q = parent; *q != NULL; q = &(*q)->next)
|
for (q = parent; *q != NULL; q = &(*q)->next)
|
||||||
if (type == heim_config_list &&
|
if (type == heim_config_list &&
|
||||||
(unsigned)type == (*q)->type &&
|
(unsigned)type == (*q)->type &&
|
||||||
strcmp_du(name, (*q)->name) == 0)
|
strcmp(name, (*q)->name) == 0)
|
||||||
return *q;
|
return *q;
|
||||||
*q = calloc(1, sizeof(**q));
|
*q = calloc(1, sizeof(**q));
|
||||||
if (*q == NULL)
|
if (*q == NULL)
|
||||||
@@ -808,7 +788,7 @@ vget_next(heim_context context,
|
|||||||
const char *p = va_arg(args, const char *);
|
const char *p = va_arg(args, const char *);
|
||||||
|
|
||||||
while (b != NULL) {
|
while (b != NULL) {
|
||||||
if (strcmp_du(b->name, name) == 0) {
|
if (strcmp(b->name, name) == 0) {
|
||||||
if (b->type == (unsigned)type && p == NULL) {
|
if (b->type == (unsigned)type && p == NULL) {
|
||||||
*pointer = b;
|
*pointer = b;
|
||||||
return b->u.generic;
|
return b->u.generic;
|
||||||
@@ -846,7 +826,7 @@ heim_config_vget_next(heim_context context,
|
|||||||
/* we were called again, so just look for more entries with the
|
/* we were called again, so just look for more entries with the
|
||||||
same name and type */
|
same name and type */
|
||||||
for (b = (*pointer)->next; b != NULL; b = b->next) {
|
for (b = (*pointer)->next; b != NULL; b = b->next) {
|
||||||
if(strcmp_du(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) {
|
if(strcmp(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) {
|
||||||
*pointer = b;
|
*pointer = b;
|
||||||
return b->u.generic;
|
return b->u.generic;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-28
@@ -355,12 +355,11 @@ open_file(heim_context context, heim_log_facility *fac, int min, int max,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static heim_error_code
|
heim_error_code
|
||||||
addlog_dest(heim_context context, heim_log_facility *f,
|
heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig)
|
||||||
const char *orig, int default_min, int default_max)
|
|
||||||
{
|
{
|
||||||
heim_error_code ret = 0;
|
heim_error_code ret = 0;
|
||||||
int min = default_min, max = default_max, n;
|
int min = 0, max = 3, n;
|
||||||
char c;
|
char c;
|
||||||
const char *p = orig;
|
const char *p = orig;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -394,6 +393,8 @@ addlog_dest(heim_context context, heim_log_facility *f,
|
|||||||
return HEIM_ERR_LOG_PARSE;
|
return HEIM_ERR_LOG_PARSE;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
|
} else {
|
||||||
|
max = 5;
|
||||||
}
|
}
|
||||||
if (strcmp(p, "STDERR") == 0) {
|
if (strcmp(p, "STDERR") == 0) {
|
||||||
ret = open_file(context, f, min, max, NULL, "a", stderr,
|
ret = open_file(context, f, min, max, NULL, "a", stderr,
|
||||||
@@ -444,12 +445,6 @@ addlog_dest(heim_context context, heim_log_facility *f,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
heim_error_code
|
|
||||||
heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig)
|
|
||||||
{
|
|
||||||
return addlog_dest(context, f, orig, 0, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
heim_error_code
|
heim_error_code
|
||||||
heim_openlog(heim_context context,
|
heim_openlog(heim_context context,
|
||||||
const char *program,
|
const char *program,
|
||||||
@@ -653,9 +648,9 @@ heim_add_warn_dest(heim_context context, const char *program,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static heim_error_code
|
heim_error_code
|
||||||
add_debug_dest(heim_context context, const char *program,
|
heim_add_debug_dest(heim_context context, const char *program,
|
||||||
const char *log_spec, int default_min, int default_max)
|
const char *log_spec)
|
||||||
{
|
{
|
||||||
heim_log_facility *fac;
|
heim_log_facility *fac;
|
||||||
heim_error_code ret;
|
heim_error_code ret;
|
||||||
@@ -667,26 +662,12 @@ add_debug_dest(heim_context context, const char *program,
|
|||||||
heim_set_debug_dest(context, fac);
|
heim_set_debug_dest(context, fac);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = addlog_dest(context, fac, log_spec, default_min, default_max);
|
ret = heim_addlog_dest(context, fac, log_spec);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
heim_error_code
|
|
||||||
heim_add_debug_dest(heim_context context, const char *program,
|
|
||||||
const char *log_spec)
|
|
||||||
{
|
|
||||||
return add_debug_dest(context, program, log_spec, 0, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
heim_error_code
|
|
||||||
heim_add_trace_dest(heim_context context, const char *program,
|
|
||||||
const char *log_spec)
|
|
||||||
{
|
|
||||||
return add_debug_dest(context, program, log_spec, 0, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct heim_audit_kv_tuple {
|
struct heim_audit_kv_tuple {
|
||||||
heim_string_t key;
|
heim_string_t key;
|
||||||
heim_object_t value;
|
heim_object_t value;
|
||||||
|
|||||||
@@ -142,83 +142,6 @@ test_rwlock(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
file_contains(const char *filename, const char *needle)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
FILE *f;
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
f = fopen(filename, "r");
|
|
||||||
if (f == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), f) != NULL) {
|
|
||||||
if (strstr(buf, needle) != NULL) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
test_log_dest(void)
|
|
||||||
{
|
|
||||||
const char *normal = "test-log-dest.log";
|
|
||||||
const char *trace = "test-trace-dest.log";
|
|
||||||
const char *explicit = "test-trace-explicit-dest.log";
|
|
||||||
heim_log_facility *fac = NULL;
|
|
||||||
heim_context context;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
unlink(normal);
|
|
||||||
unlink(trace);
|
|
||||||
unlink(explicit);
|
|
||||||
|
|
||||||
context = heim_context_init();
|
|
||||||
heim_assert(context != NULL, "heim_context_init failed");
|
|
||||||
|
|
||||||
ret = heim_initlog(context, "test_base", &fac);
|
|
||||||
heim_assert(ret == 0, "heim_initlog failed");
|
|
||||||
ret = heim_addlog_dest(context, fac, normal);
|
|
||||||
heim_assert(ret == 0, "heim_addlog_dest failed");
|
|
||||||
|
|
||||||
heim_log(context, fac, 10, "normal level 10");
|
|
||||||
heim_log(context, fac, 5, "normal level 5");
|
|
||||||
heim_closelog(context, fac);
|
|
||||||
|
|
||||||
heim_assert(!file_contains(normal, "normal level 10"),
|
|
||||||
"normal log destination traced level 10 by default");
|
|
||||||
heim_assert(file_contains(normal, "normal level 5"),
|
|
||||||
"normal log destination did not log level 5 by default");
|
|
||||||
|
|
||||||
ret = heim_add_trace_dest(context, "test_base", trace);
|
|
||||||
heim_assert(ret == 0, "heim_add_trace_dest failed");
|
|
||||||
ret = heim_add_trace_dest(context, "test_base",
|
|
||||||
"5/FILE:test-trace-explicit-dest.log");
|
|
||||||
heim_assert(ret == 0, "heim_add_trace_dest with explicit level failed");
|
|
||||||
|
|
||||||
heim_debug(context, 10, "trace level 10");
|
|
||||||
heim_debug(context, 5, "trace level 5");
|
|
||||||
|
|
||||||
heim_assert(file_contains(trace, "trace level 10"),
|
|
||||||
"trace log destination did not trace level 10 by default");
|
|
||||||
heim_assert(!file_contains(explicit, "trace level 10"),
|
|
||||||
"explicit trace destination ignored its level filter");
|
|
||||||
heim_assert(file_contains(explicit, "trace level 5"),
|
|
||||||
"explicit trace destination did not log matching level");
|
|
||||||
|
|
||||||
heim_context_free(&context);
|
|
||||||
|
|
||||||
unlink(normal);
|
|
||||||
unlink(trace);
|
|
||||||
unlink(explicit);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
test_dict(void)
|
test_dict(void)
|
||||||
{
|
{
|
||||||
@@ -1442,7 +1365,6 @@ main(int argc, char **argv)
|
|||||||
res |= test_memory();
|
res |= test_memory();
|
||||||
res |= test_mutex();
|
res |= test_mutex();
|
||||||
res |= test_rwlock();
|
res |= test_rwlock();
|
||||||
res |= test_log_dest();
|
|
||||||
res |= test_dict();
|
res |= test_dict();
|
||||||
res |= test_auto_release();
|
res |= test_auto_release();
|
||||||
res |= test_string();
|
res |= test_string();
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ HEIMDAL_BASE_1.0 {
|
|||||||
heim_abort;
|
heim_abort;
|
||||||
heim_abortv;
|
heim_abortv;
|
||||||
heim_add_debug_dest;
|
heim_add_debug_dest;
|
||||||
heim_add_trace_dest;
|
|
||||||
heim_add_et_list;
|
heim_add_et_list;
|
||||||
heim_addlog_dest;
|
heim_addlog_dest;
|
||||||
heim_addlog_func;
|
heim_addlog_func;
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
.Fl r
|
.Fl r
|
||||||
.Op Fl MNln
|
.Op Fl MNln
|
||||||
.Op Fl C Ar ccache
|
.Op Fl C Ar ccache
|
||||||
.Op Fl L Ar localuser
|
|
||||||
.Op Fl S Ar maxsize
|
.Op Fl S Ar maxsize
|
||||||
.Op Fl c count
|
.Op Fl c count
|
||||||
.Op Fl m mech
|
.Op Fl m mech
|
||||||
@@ -36,11 +35,6 @@ write an accepted delegated credential into
|
|||||||
This only makes sense if
|
This only makes sense if
|
||||||
.Fl r
|
.Fl r
|
||||||
is specified.
|
is specified.
|
||||||
.It Fl L Ar localuser
|
|
||||||
try to authorize as
|
|
||||||
.Ar localuser
|
|
||||||
with
|
|
||||||
.Fn gss_authorize_localname .
|
|
||||||
.It Fl D
|
.It Fl D
|
||||||
delegate credentials.
|
delegate credentials.
|
||||||
This only makes sense as a client, that is when
|
This only makes sense as a client, that is when
|
||||||
|
|||||||
+7
-37
@@ -435,13 +435,11 @@ initiate_many(gss_name_t service, int delegate, int negotiate, int memcache,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
accept_one(gss_name_t service, const char *ccname, const char *localuser,
|
accept_one(gss_name_t service, const char *ccname, int negotiate)
|
||||||
int negotiate)
|
|
||||||
{
|
{
|
||||||
gss_cred_id_t cred = NULL;
|
gss_cred_id_t cred = NULL;
|
||||||
gss_cred_id_t deleg_creds = NULL;
|
gss_cred_id_t deleg_creds = NULL;
|
||||||
gss_name_t client = GSS_C_NO_NAME;
|
gss_name_t client;
|
||||||
gss_name_t lname = GSS_C_NO_NAME;
|
|
||||||
gss_OID mech_oid;
|
gss_OID mech_oid;
|
||||||
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
||||||
gss_buffer_desc in = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc in = GSS_C_EMPTY_BUFFER;
|
||||||
@@ -497,23 +495,8 @@ accept_one(gss_name_t service, const char *ccname, const char *localuser,
|
|||||||
printf("Authenticated: %.*s\n", (int)dname.length,
|
printf("Authenticated: %.*s\n", (int)dname.length,
|
||||||
(char *)dname.value);
|
(char *)dname.value);
|
||||||
(void) gss_release_buffer(&min, &dname);
|
(void) gss_release_buffer(&min, &dname);
|
||||||
|
(void) gss_release_name(&min, &client);
|
||||||
if (localuser) {
|
(void) gss_delete_sec_context(&min, &ctx, GSS_C_NO_BUFFER);
|
||||||
gss_buffer_desc lnamebuf;
|
|
||||||
|
|
||||||
lnamebuf.length = strlen(localuser);
|
|
||||||
lnamebuf.value = rk_UNCONST(localuser);
|
|
||||||
|
|
||||||
maj = gss_import_name(&min, &lnamebuf,
|
|
||||||
GSS_C_NT_USER_NAME, &lname);
|
|
||||||
GBAIL("gss_import_name", maj, min);
|
|
||||||
|
|
||||||
maj = gss_authorize_localname(&min, client, lname);
|
|
||||||
GBAIL("gss_authorize_localname", maj, min);
|
|
||||||
|
|
||||||
if (!nflag)
|
|
||||||
printf("Authorized: %s\n", localuser);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ccname) {
|
if (ccname) {
|
||||||
#ifdef HAVE_GSS_STORE_CRED_INTO
|
#ifdef HAVE_GSS_STORE_CRED_INTO
|
||||||
@@ -549,12 +532,6 @@ bail:
|
|||||||
gss_release_cred(&min, &cred);
|
gss_release_cred(&min, &cred);
|
||||||
if (deleg_creds)
|
if (deleg_creds)
|
||||||
gss_release_cred(&min, &deleg_creds);
|
gss_release_cred(&min, &deleg_creds);
|
||||||
if (lname)
|
|
||||||
gss_release_name(&min, &lname);
|
|
||||||
if (client)
|
|
||||||
gss_release_name(&min, &client);
|
|
||||||
if (ctx != GSS_C_NO_CONTEXT)
|
|
||||||
gss_delete_sec_context(&min, &ctx, GSS_C_NO_BUFFER);
|
|
||||||
|
|
||||||
free(in.value);
|
free(in.value);
|
||||||
|
|
||||||
@@ -608,8 +585,8 @@ usage(int ecode)
|
|||||||
{
|
{
|
||||||
FILE *f = ecode == 0 ? stdout : stderr;
|
FILE *f = ecode == 0 ? stdout : stderr;
|
||||||
fprintf(f, "Usage: gss-token [-DNn] [-c count] service@host\n");
|
fprintf(f, "Usage: gss-token [-DNn] [-c count] service@host\n");
|
||||||
fprintf(f, " gss-token -r [-Nln] [-C ccache] [-L localuser] "
|
fprintf(f, " gss-token -r [-Nln] [-C ccache] [-c count] "
|
||||||
"[-c count] [service@host]\n");
|
"[service@host]\n");
|
||||||
exit(ecode);
|
exit(ecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,14 +606,12 @@ main(int argc, char **argv)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
int optidx = 0;
|
int optidx = 0;
|
||||||
char *ccname = NULL;
|
char *ccname = NULL;
|
||||||
char *localuser = NULL;
|
|
||||||
char *mech = NULL;
|
char *mech = NULL;
|
||||||
struct getargs args[] = {
|
struct getargs args[] = {
|
||||||
{ "help", 'h', arg_flag, &hflag, NULL, NULL },
|
{ "help", 'h', arg_flag, &hflag, NULL, NULL },
|
||||||
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
||||||
{ NULL, 'C', arg_string, &ccname, NULL, NULL },
|
{ NULL, 'C', arg_string, &ccname, NULL, NULL },
|
||||||
{ NULL, 'D', arg_flag, &Dflag, NULL, NULL },
|
{ NULL, 'D', arg_flag, &Dflag, NULL, NULL },
|
||||||
{ NULL, 'L', arg_string, &localuser, NULL, NULL },
|
|
||||||
{ NULL, 'M', arg_flag, &Mflag, NULL, NULL },
|
{ NULL, 'M', arg_flag, &Mflag, NULL, NULL },
|
||||||
{ NULL, 'N', arg_flag, &Nflag, NULL, NULL },
|
{ NULL, 'N', arg_flag, &Nflag, NULL, NULL },
|
||||||
{ NULL, 'S', arg_integer, &Sflag, NULL, NULL },
|
{ NULL, 'S', arg_integer, &Sflag, NULL, NULL },
|
||||||
@@ -687,11 +662,6 @@ main(int argc, char **argv)
|
|||||||
"make sense without -r.\n");
|
"make sense without -r.\n");
|
||||||
usage(1);
|
usage(1);
|
||||||
}
|
}
|
||||||
if (localuser) {
|
|
||||||
fprintf(stderr, "Specifying a local user doesn't make "
|
|
||||||
"sense without -r.\n");
|
|
||||||
usage(1);
|
|
||||||
}
|
|
||||||
ret = initiate_many(service, Dflag, Nflag, Mflag, count);
|
ret = initiate_many(service, Dflag, Nflag, Mflag, count);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -703,7 +673,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = accept_one(service, ccname, localuser, Nflag);
|
ret = accept_one(service, ccname, Nflag);
|
||||||
} while (lflag && !ret && !feof(stdin));
|
} while (lflag && !ret && !feof(stdin));
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|||||||
@@ -926,7 +926,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred_from
|
|||||||
NULL, time_rec, NULL, actual_mechs);
|
NULL, time_rec, NULL, actual_mechs);
|
||||||
if (ret != GSS_S_COMPLETE) {
|
if (ret != GSS_S_COMPLETE) {
|
||||||
if (handle->mechanisms != NULL)
|
if (handle->mechanisms != NULL)
|
||||||
gss_release_oid_set(minor_status, &handle->mechanisms);
|
gss_release_oid_set(NULL, &handle->mechanisms);
|
||||||
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
|
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
|
||||||
krb5_free_principal(context, handle->principal);
|
krb5_free_principal(context, handle->principal);
|
||||||
free(handle);
|
free(handle);
|
||||||
|
|||||||
@@ -238,7 +238,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred_from (
|
|||||||
|
|
||||||
failure:
|
failure:
|
||||||
if (handle) {
|
if (handle) {
|
||||||
OM_uint32 tmp_status;
|
|
||||||
if (handle->principal)
|
if (handle->principal)
|
||||||
krb5_free_principal(context, handle->principal);
|
krb5_free_principal(context, handle->principal);
|
||||||
if (handle->keytab)
|
if (handle->keytab)
|
||||||
@@ -246,7 +245,7 @@ failure:
|
|||||||
if (handle->ccache)
|
if (handle->ccache)
|
||||||
krb5_cc_destroy(context, handle->ccache);
|
krb5_cc_destroy(context, handle->ccache);
|
||||||
if (handle->mechanisms)
|
if (handle->mechanisms)
|
||||||
gss_release_oid_set(&tmp_status, &handle->mechanisms);
|
gss_release_oid_set(NULL, &handle->mechanisms);
|
||||||
free(handle);
|
free(handle);
|
||||||
}
|
}
|
||||||
if (cred && output_cred_handle)
|
if (cred && output_cred_handle)
|
||||||
|
|||||||
+15
-15
@@ -308,7 +308,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, p, p, 8) != 8) {
|
EVP_Cipher(rc4_key, p, p, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -392,7 +392,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, (void *)k6_data, NULL, 0) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, (void *)k6_data, NULL, 0) != 1 ||
|
||||||
EVP_Cipher(rc4_key, SND_SEQ, p, 8) != 8) {
|
EVP_Cipher(rc4_key, SND_SEQ, p, 8) != 1) {
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
@@ -553,7 +553,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen) != 8 + datalen) {
|
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -581,7 +581,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8) != 8) {
|
EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -690,7 +690,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8) != 8) {
|
EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -747,8 +747,8 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 8 ||
|
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 1 ||
|
||||||
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen) != datalen) {
|
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1149,7 +1149,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
/* Confounder */
|
/* Confounder */
|
||||||
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8) != 8) {
|
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1166,7 +1166,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
||||||
iov[i].buffer.value, iov[i].buffer.length) != iov[i].buffer.length) {
|
iov[i].buffer.value, iov[i].buffer.length) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1177,7 +1177,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
/* Padding */
|
/* Padding */
|
||||||
if (padding &&
|
if (padding &&
|
||||||
EVP_Cipher(rc4_key, padding->buffer.value,
|
EVP_Cipher(rc4_key, padding->buffer.value,
|
||||||
padding->buffer.value, padding->buffer.length) != padding->buffer.length) {
|
padding->buffer.value, padding->buffer.length) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1206,7 +1206,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, p0 + 8, p0 + 8, 8) != 8 /* SND_SEQ */) {
|
EVP_Cipher(rc4_key, p0 + 8, p0 + 8, 8) != 1 /* SND_SEQ */) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1357,7 +1357,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
EVP_Cipher(rc4_key, snd_seq, p0 + 8, 8) != 8 /* SND_SEQ */) {
|
EVP_Cipher(rc4_key, snd_seq, p0 + 8, 8) != 1 /* SND_SEQ */) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1410,7 +1410,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||||
/* Confounder */
|
/* Confounder */
|
||||||
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 8) {
|
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1427,7 +1427,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
||||||
iov[i].buffer.value, iov[i].buffer.length) != iov[i].buffer.length) {
|
iov[i].buffer.value, iov[i].buffer.length) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
@@ -1438,7 +1438,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
|||||||
/* Padding */
|
/* Padding */
|
||||||
if (padding &&
|
if (padding &&
|
||||||
EVP_Cipher(rc4_key, padding->buffer.value,
|
EVP_Cipher(rc4_key, padding->buffer.value,
|
||||||
padding->buffer.value, padding->buffer.length) != padding->buffer.length) {
|
padding->buffer.value, padding->buffer.length) != 1) {
|
||||||
EVP_CIPHER_CTX_free(rc4_key);
|
EVP_CIPHER_CTX_free(rc4_key);
|
||||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||||
|
|||||||
@@ -100,12 +100,11 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_context (
|
|||||||
return GSS_S_COMPLETE;
|
return GSS_S_COMPLETE;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
{ OM_uint32 tmp_status;
|
|
||||||
if (src_name)
|
if (src_name)
|
||||||
_gsskrb5_release_name(&tmp_status, src_name);
|
_gsskrb5_release_name(NULL, src_name);
|
||||||
if (targ_name)
|
if (targ_name)
|
||||||
_gsskrb5_release_name(&tmp_status, targ_name);
|
_gsskrb5_release_name(NULL, targ_name);
|
||||||
}
|
|
||||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_mechs_for_name (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
OM_uint32 ret;
|
OM_uint32 ret;
|
||||||
OM_uint32 tmp_status;
|
|
||||||
|
|
||||||
ret = gss_create_empty_oid_set(minor_status, mech_types);
|
ret = gss_create_empty_oid_set(minor_status, mech_types);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -50,7 +49,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_mechs_for_name (
|
|||||||
GSS_KRB5_MECHANISM,
|
GSS_KRB5_MECHANISM,
|
||||||
mech_types);
|
mech_types);
|
||||||
if (ret)
|
if (ret)
|
||||||
gss_release_oid_set(&tmp_status, mech_types);
|
gss_release_oid_set(NULL, mech_types);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_names_for_mech (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
OM_uint32 ret;
|
OM_uint32 ret;
|
||||||
OM_uint32 tmp_status;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
*minor_status = 0;
|
*minor_status = 0;
|
||||||
@@ -72,7 +71,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_names_for_mech (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret != GSS_S_COMPLETE)
|
if (ret != GSS_S_COMPLETE)
|
||||||
gss_release_oid_set(&tmp_status, name_types);
|
gss_release_oid_set(NULL, name_types);
|
||||||
|
|
||||||
return GSS_S_COMPLETE;
|
return GSS_S_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,25 +83,8 @@ set_proc(OM_uint32 *minor, gss_buffer_set_t env)
|
|||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < env->count; i++) {
|
for (i = 0; i < env->count; i++)
|
||||||
char *var = (char *)env->elements[i].value;
|
putenv(env->elements[i].value);
|
||||||
char *eq = strchr(var, '=');
|
|
||||||
char *val;
|
|
||||||
int e;
|
|
||||||
|
|
||||||
if (eq == NULL) {
|
|
||||||
*minor = EINVAL;
|
|
||||||
return GSS_S_FAILURE;
|
|
||||||
}
|
|
||||||
val = eq + 1;
|
|
||||||
*eq = '\0';
|
|
||||||
e = setenv(var, val, 1);
|
|
||||||
*eq = '=';
|
|
||||||
if (e != 0) {
|
|
||||||
*minor = errno ? errno : EINVAL;
|
|
||||||
return GSS_S_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return GSS_S_COMPLETE;
|
return GSS_S_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,14 +265,12 @@ gss_accept_sec_context(OM_uint32 *minor_status,
|
|||||||
*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
|
*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
|
||||||
_mg_buffer_zero(output_token);
|
_mg_buffer_zero(output_token);
|
||||||
|
|
||||||
_gss_mg_log(10, "gss-asc: enter ctx=%p", ctx);
|
|
||||||
if (!*context_handle) {
|
if (!*context_handle) {
|
||||||
ctx = calloc(1, sizeof(*ctx));
|
ctx = calloc(1, sizeof(*ctx));
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return (GSS_S_DEFECTIVE_TOKEN);
|
return (GSS_S_DEFECTIVE_TOKEN);
|
||||||
}
|
}
|
||||||
_gss_mg_log(10, "gss-asc: allocated ctx=%p", ctx);
|
|
||||||
*context_handle = (gss_ctx_id_t)ctx;
|
*context_handle = (gss_ctx_id_t)ctx;
|
||||||
ctx->gc_initial = 1;
|
ctx->gc_initial = 1;
|
||||||
}
|
}
|
||||||
@@ -320,9 +318,6 @@ gss_accept_sec_context(OM_uint32 *minor_status,
|
|||||||
&mech_ret_flags,
|
&mech_ret_flags,
|
||||||
time_rec,
|
time_rec,
|
||||||
&delegated_mc);
|
&delegated_mc);
|
||||||
_gss_mg_log(10, "gss-asc: ctx=%p tried \"%s\", "
|
|
||||||
"returned %u", ctx, m->gm_name,
|
|
||||||
major_status);
|
|
||||||
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
|
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
|
||||||
/*
|
/*
|
||||||
* Try to retain and output one error token for
|
* Try to retain and output one error token for
|
||||||
@@ -365,9 +360,6 @@ gss_accept_sec_context(OM_uint32 *minor_status,
|
|||||||
&mech_ret_flags,
|
&mech_ret_flags,
|
||||||
time_rec,
|
time_rec,
|
||||||
&delegated_mc);
|
&delegated_mc);
|
||||||
_gss_mg_log(10, "gss-asc: ctx=%p tried \"%s\", "
|
|
||||||
"returned %u", ctx, m->gm_name,
|
|
||||||
major_status);
|
|
||||||
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
|
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
|
||||||
if (output_token->length &&
|
if (output_token->length &&
|
||||||
defective_token_error.length == 0) {
|
defective_token_error.length == 0) {
|
||||||
@@ -518,8 +510,7 @@ got_one:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_gss_mg_log(10, "gss-asc: ctx=%p return %d/%d", ctx,
|
_gss_mg_log(10, "gss-asc: return %d/%d", (int)major_status, (int)*minor_status);
|
||||||
(int)major_status, (int)*minor_status);
|
|
||||||
|
|
||||||
if (ret_flags)
|
if (ret_flags)
|
||||||
*ret_flags = mech_ret_flags;
|
*ret_flags = mech_ret_flags;
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ gss_display_name(OM_uint32 *minor_status,
|
|||||||
struct _gss_name *name = rk_UNCONST(input_name);
|
struct _gss_name *name = rk_UNCONST(input_name);
|
||||||
struct _gss_mechanism_name *mn;
|
struct _gss_mechanism_name *mn;
|
||||||
|
|
||||||
_gss_mg_log(10, "gdn: enter gss_display_name: %p", input_name);
|
|
||||||
_mg_buffer_zero(output_name_buffer);
|
_mg_buffer_zero(output_name_buffer);
|
||||||
if (output_name_type)
|
if (output_name_type)
|
||||||
*output_name_type = GSS_C_NO_OID;
|
*output_name_type = GSS_C_NO_OID;
|
||||||
@@ -69,8 +68,6 @@ gss_display_name(OM_uint32 *minor_status,
|
|||||||
return (GSS_S_COMPLETE);
|
return (GSS_S_COMPLETE);
|
||||||
} else {
|
} else {
|
||||||
HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) {
|
HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) {
|
||||||
_gss_mg_log(10, "gdn: trying mech \"%s\"",
|
|
||||||
mn->gmn_mech->gm_name);
|
|
||||||
major_status = mn->gmn_mech->gm_display_name(
|
major_status = mn->gmn_mech->gm_display_name(
|
||||||
minor_status, mn->gmn_name,
|
minor_status, mn->gmn_name,
|
||||||
output_name_buffer,
|
output_name_buffer,
|
||||||
|
|||||||
@@ -28,8 +28,6 @@
|
|||||||
|
|
||||||
#include "mech_locl.h"
|
#include "mech_locl.h"
|
||||||
|
|
||||||
#include <vis.h>
|
|
||||||
|
|
||||||
static OM_uint32
|
static OM_uint32
|
||||||
_gss_import_export_name(OM_uint32 *minor_status,
|
_gss_import_export_name(OM_uint32 *minor_status,
|
||||||
const gss_buffer_t input_name_buffer,
|
const gss_buffer_t input_name_buffer,
|
||||||
@@ -46,8 +44,6 @@ _gss_import_export_name(OM_uint32 *minor_status,
|
|||||||
gss_name_t new_canonical_name;
|
gss_name_t new_canonical_name;
|
||||||
int composite = 0;
|
int composite = 0;
|
||||||
|
|
||||||
_gss_mg_log(10, "gin: importing exported name");
|
|
||||||
|
|
||||||
*minor_status = 0;
|
*minor_status = 0;
|
||||||
*output_name = 0;
|
*output_name = 0;
|
||||||
|
|
||||||
@@ -173,32 +169,6 @@ _gss_import_export_name(OM_uint32 *minor_status,
|
|||||||
return (GSS_S_COMPLETE);
|
return (GSS_S_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
log_import_name(gss_buffer_t input_name_buffer)
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
if (!_gss_mg_log_level(10))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (input_name_buffer->length > (SIZE_MAX - 1) / 4) {
|
|
||||||
_gss_mg_log(10, "gin: importing name (%zu bytes)",
|
|
||||||
input_name_buffer->length);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = input_name_buffer->length * 4 + 1;
|
|
||||||
name = malloc(len);
|
|
||||||
if (name == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
strsvisx(name, input_name_buffer->value, input_name_buffer->length,
|
|
||||||
VIS_CSTYLE | VIS_TAB | VIS_NL, "\"");
|
|
||||||
_gss_mg_log(10, "gin: importing name \"%s\"", name);
|
|
||||||
free(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a GGS-API name from contiguous string to internal form.
|
* Convert a GGS-API name from contiguous string to internal form.
|
||||||
*
|
*
|
||||||
@@ -260,7 +230,6 @@ gss_import_name(OM_uint32 *minor_status,
|
|||||||
name_type, output_name);
|
name_type, output_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
log_import_name(input_name_buffer);
|
|
||||||
|
|
||||||
*minor_status = 0;
|
*minor_status = 0;
|
||||||
name = _gss_create_name(NULL, NULL);
|
name = _gss_create_name(NULL, NULL);
|
||||||
@@ -293,9 +262,6 @@ gss_import_name(OM_uint32 *minor_status,
|
|||||||
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
||||||
int present = 0;
|
int present = 0;
|
||||||
|
|
||||||
_gss_mg_log(10, "gin: attempting mech \"%s\"",
|
|
||||||
m->gm_mech.gm_name);
|
|
||||||
|
|
||||||
if ((m->gm_mech.gm_flags & GM_USE_MG_NAME))
|
if ((m->gm_mech.gm_flags & GM_USE_MG_NAME))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -167,8 +167,7 @@ do { \
|
|||||||
m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \
|
m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \
|
||||||
if (!m->gm_mech.gm_ ## name || \
|
if (!m->gm_mech.gm_ ## name || \
|
||||||
m->gm_mech.gm_ ##name == gss_ ## name) { \
|
m->gm_mech.gm_ ##name == gss_ ## name) { \
|
||||||
_gss_mg_log(1, "can't find symbol gss_" #name \
|
_gss_mg_log(1, "can't find symbol gss_" #name "\n"); \
|
||||||
" in %s", lib); \
|
|
||||||
goto bad; \
|
goto bad; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -335,11 +334,9 @@ _gss_load_mech(void)
|
|||||||
/*
|
/*
|
||||||
* Check for duplicates, already loaded mechs.
|
* Check for duplicates, already loaded mechs.
|
||||||
*/
|
*/
|
||||||
_gss_mg_log(10, "loading \"%s\"", name);
|
|
||||||
found = 0;
|
found = 0;
|
||||||
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
||||||
if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech_oid)) {
|
if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech_oid)) {
|
||||||
_gss_mg_log(10, "duplicate mech, not loading");
|
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -349,7 +346,7 @@ _gss_load_mech(void)
|
|||||||
|
|
||||||
so = dlopen(lib, RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP);
|
so = dlopen(lib, RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP);
|
||||||
if (so == NULL) {
|
if (so == NULL) {
|
||||||
_gss_mg_log(1, "dlopen: %s", dlerror());
|
_gss_mg_log(1, "dlopen: %s\n", dlerror());
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,8 +99,6 @@ static int help_flag = 0;
|
|||||||
static int env_flag = 0;
|
static int env_flag = 0;
|
||||||
static int def_flag = 0;
|
static int def_flag = 0;
|
||||||
static int overwrite_flag = 0;
|
static int overwrite_flag = 0;
|
||||||
static int store_cred_flag = 0;
|
|
||||||
static char *password = NULL;
|
|
||||||
|
|
||||||
static struct getargs args[] = {
|
static struct getargs args[] = {
|
||||||
{"version", 0, arg_flag, &version_flag, "print version", NULL },
|
{"version", 0, arg_flag, &version_flag, "print version", NULL },
|
||||||
@@ -111,133 +109,16 @@ static struct getargs args[] = {
|
|||||||
"switch credential store default principal", NULL },
|
"switch credential store default principal", NULL },
|
||||||
{"overwrite", 0, arg_flag, &overwrite_flag,
|
{"overwrite", 0, arg_flag, &overwrite_flag,
|
||||||
"overwrite matching credential", NULL },
|
"overwrite matching credential", NULL },
|
||||||
{"store-cred", 0, arg_flag, &store_cred_flag,
|
|
||||||
"use gss_store_cred instead of gss_store_cred_into2", NULL },
|
|
||||||
{"password", 0, arg_string, &password,
|
|
||||||
"acquire source credential with this password", "password" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(int ret)
|
usage(int ret)
|
||||||
{
|
{
|
||||||
arg_printusage(args, sizeof(args)/sizeof(*args),
|
arg_printusage(args, sizeof(args)/sizeof(*args),
|
||||||
NULL, "from_ccache to_ccache | source_name target_name");
|
NULL, "from_ccache to_ccache");
|
||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
add_krb5_mech(gss_OID_set *mechs)
|
|
||||||
{
|
|
||||||
OM_uint32 major, minor;
|
|
||||||
|
|
||||||
major = gss_create_empty_oid_set(&minor, mechs);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_C_NO_OID,
|
|
||||||
"failed to create OID set");
|
|
||||||
|
|
||||||
major = gss_add_oid_set_member(&minor, GSS_KRB5_MECHANISM, mechs);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_C_NO_OID,
|
|
||||||
"failed to add krb5 mechanism to OID set");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
acquire_from_password(const char *source_name,
|
|
||||||
const char *source_password,
|
|
||||||
gss_cred_id_t *cred)
|
|
||||||
{
|
|
||||||
OM_uint32 major, minor;
|
|
||||||
gss_buffer_desc namebuf, pwbuf;
|
|
||||||
gss_name_t name = GSS_C_NO_NAME;
|
|
||||||
gss_OID_set mechs = GSS_C_NO_OID_SET;
|
|
||||||
|
|
||||||
namebuf.value = rk_UNCONST(source_name);
|
|
||||||
namebuf.length = strlen(source_name);
|
|
||||||
major = gss_import_name(&minor, &namebuf, GSS_C_NT_USER_NAME, &name);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_C_NO_OID,
|
|
||||||
"failed to import source name %s", source_name);
|
|
||||||
|
|
||||||
pwbuf.value = rk_UNCONST(source_password);
|
|
||||||
pwbuf.length = strlen(source_password);
|
|
||||||
add_krb5_mech(&mechs);
|
|
||||||
major = gss_acquire_cred_with_password(&minor, name, &pwbuf,
|
|
||||||
GSS_C_INDEFINITE, mechs,
|
|
||||||
GSS_C_INITIATE, cred, NULL, NULL);
|
|
||||||
(void) gss_release_oid_set(&minor, &mechs);
|
|
||||||
(void) gss_release_name(&minor, &name);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
|
||||||
"failed to acquire creds with password for %s", source_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_init_sec_context(gss_cred_id_t cred, const char *target)
|
|
||||||
{
|
|
||||||
OM_uint32 major, minor;
|
|
||||||
gss_buffer_desc namebuf;
|
|
||||||
gss_buffer_desc output_token = { 0, NULL };
|
|
||||||
gss_name_t target_name = GSS_C_NO_NAME;
|
|
||||||
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
|
||||||
|
|
||||||
namebuf.value = rk_UNCONST(target);
|
|
||||||
namebuf.length = strlen(target);
|
|
||||||
major = gss_import_name(&minor, &namebuf, GSS_C_NT_HOSTBASED_SERVICE,
|
|
||||||
&target_name);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_C_NO_OID,
|
|
||||||
"failed to import target name %s", target);
|
|
||||||
|
|
||||||
major = gss_init_sec_context(&minor, cred, &ctx, target_name,
|
|
||||||
GSS_KRB5_MECHANISM, 0, GSS_C_INDEFINITE,
|
|
||||||
GSS_C_NO_CHANNEL_BINDINGS,
|
|
||||||
GSS_C_NO_BUFFER, NULL, &output_token,
|
|
||||||
NULL, NULL);
|
|
||||||
(void) gss_release_buffer(&minor, &output_token);
|
|
||||||
(void) gss_delete_sec_context(&minor, &ctx, GSS_C_NO_BUFFER);
|
|
||||||
(void) gss_release_name(&minor, &target_name);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
|
||||||
"failed to use source cred for %s after storing", target);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
acquire_from_ccache(const char *ccache, gss_cred_id_t *cred)
|
|
||||||
{
|
|
||||||
OM_uint32 major, minor;
|
|
||||||
gss_key_value_element_desc element;
|
|
||||||
gss_key_value_set_desc store;
|
|
||||||
|
|
||||||
element.key = "ccache";
|
|
||||||
element.value = ccache;
|
|
||||||
store.count = 1;
|
|
||||||
store.elements = &element;
|
|
||||||
|
|
||||||
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
|
|
||||||
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
|
|
||||||
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
|
|
||||||
&store, cred, NULL, NULL, NULL);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
|
||||||
"failed to acquire stored creds from %s", ccache);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_default_ccache(gss_cred_id_t from_cred, const char *target)
|
|
||||||
{
|
|
||||||
OM_uint32 minor;
|
|
||||||
const char *ccache = getenv("KRB5CCNAME");
|
|
||||||
gss_cred_id_t to_cred = GSS_C_NO_CREDENTIAL;
|
|
||||||
|
|
||||||
if (ccache == NULL)
|
|
||||||
errx(1, "KRB5CCNAME not set");
|
|
||||||
|
|
||||||
acquire_from_ccache(ccache, &to_cred);
|
|
||||||
check_init_sec_context(from_cred, target);
|
|
||||||
check_init_sec_context(to_cred, target);
|
|
||||||
(void) gss_release_cred(&minor, &to_cred);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -276,42 +157,30 @@ main(int argc, char **argv)
|
|||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
errx(1, "too many arguments");
|
errx(1, "too many arguments");
|
||||||
|
|
||||||
if (password) {
|
from_elements.key = "ccache";
|
||||||
if (!store_cred_flag)
|
from_elements.value = argv[0];
|
||||||
errx(1, "--password requires --store-cred");
|
from.count = 1;
|
||||||
acquire_from_password(argv[0], password, &from_cred);
|
from.elements = &from_elements;
|
||||||
} else {
|
|
||||||
from_elements.key = "ccache";
|
|
||||||
from_elements.value = argv[0];
|
|
||||||
from.count = 1;
|
|
||||||
from.elements = &from_elements;
|
|
||||||
|
|
||||||
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
|
to_elements.key = "ccache";
|
||||||
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
|
to_elements.value = argv[1];
|
||||||
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
|
to.count = 1;
|
||||||
&from, &from_cred, NULL, NULL, NULL);
|
to.elements = &to_elements;
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
|
||||||
"failed to acquire creds from %s", argv[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (store_cred_flag) {
|
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
|
||||||
major = gss_store_cred(&minor, from_cred, GSS_C_INITIATE,
|
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
|
||||||
GSS_KRB5_MECHANISM, overwrite_flag, def_flag,
|
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
|
||||||
NULL, NULL);
|
&from, &from_cred, NULL, 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,
|
|
||||||
GSS_KRB5_MECHANISM, store_flags, &to, NULL,
|
|
||||||
NULL, env_flag ? &env : NULL);
|
|
||||||
}
|
|
||||||
if (major != GSS_S_COMPLETE)
|
if (major != GSS_S_COMPLETE)
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
||||||
"failed to store creds");
|
"failed to acquire creds from %s", argv[0]);
|
||||||
|
|
||||||
|
major = gss_store_cred_into2(&minor, from_cred, GSS_C_INITIATE,
|
||||||
|
GSS_KRB5_MECHANISM, store_flags, &to, NULL,
|
||||||
|
NULL, env_flag ? &env : NULL);
|
||||||
|
if (major != GSS_S_COMPLETE)
|
||||||
|
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
||||||
|
"failed to store creds into %s", argv[1]);
|
||||||
|
|
||||||
if (env_flag) {
|
if (env_flag) {
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -335,22 +204,6 @@ main(int argc, char **argv)
|
|||||||
"gss_store_cred_into2()");
|
"gss_store_cred_into2()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password)
|
|
||||||
check_default_ccache(from_cred, argv[1]);
|
|
||||||
|
|
||||||
if (store_cred_flag) {
|
|
||||||
(void) gss_release_cred(&minor, &from_cred);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
|
|
||||||
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
|
|
||||||
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
|
|
||||||
&to, &to_cred, NULL, NULL, NULL);
|
|
||||||
if (major != GSS_S_COMPLETE)
|
|
||||||
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
|
|
||||||
"failed to acquire stored creds from %s", argv[1]);
|
|
||||||
|
|
||||||
(void) gss_release_cred(&minor, &from_cred);
|
(void) gss_release_cred(&minor, &from_cred);
|
||||||
(void) gss_release_cred(&minor, &to_cred);
|
(void) gss_release_cred(&minor, &to_cred);
|
||||||
|
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ loop(gss_OID mechoid,
|
|||||||
if (*deleg_cred != GSS_C_NO_CREDENTIAL)
|
if (*deleg_cred != GSS_C_NO_CREDENTIAL)
|
||||||
errx(1, "got delegated cred but didn't expect one");
|
errx(1, "got delegated cred but didn't expect one");
|
||||||
} else if (*deleg_cred == GSS_C_NO_CREDENTIAL)
|
} else if (*deleg_cred == GSS_C_NO_CREDENTIAL)
|
||||||
errx(1, "asked for delegated cred but did get one");
|
errx(1, "asked for delegarated cred but did get one");
|
||||||
} else if (*deleg_cred != GSS_C_NO_CREDENTIAL)
|
} else if (*deleg_cred != GSS_C_NO_CREDENTIAL)
|
||||||
errx(1, "got deleg_cred cred but didn't ask");
|
errx(1, "got deleg_cred cred but didn't ask");
|
||||||
|
|
||||||
|
|||||||
@@ -149,10 +149,55 @@ hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal,
|
|||||||
* enctypes should work.
|
* enctypes should work.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Debug: record the requested principal and keytab context */
|
||||||
|
{
|
||||||
|
char *princ_name = NULL;
|
||||||
|
if (krb5_unparse_name(context, principal, &princ_name) == 0) {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: looking up principal=%s in keytab=%s kvno=%u flags=0x%x",
|
||||||
|
princ_name ? princ_name : "<unparsed>",
|
||||||
|
k->path ? k->path : "<unknown>",
|
||||||
|
(unsigned)kvno,
|
||||||
|
(unsigned)flags);
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: looking up <unparsed principal> in keytab=%s kvno=%u flags=0x%x",
|
||||||
|
k->path ? k->path : "<unknown>",
|
||||||
|
(unsigned)kvno,
|
||||||
|
(unsigned)flags);
|
||||||
|
}
|
||||||
|
free(princ_name);
|
||||||
|
}
|
||||||
|
|
||||||
ret = krb5_kt_get_entry(context, k->keytab, principal, kvno, 0, &ktentry);
|
ret = krb5_kt_get_entry(context, k->keytab, principal, kvno, 0, &ktentry);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
char *princ_name2 = NULL;
|
||||||
|
if (krb5_unparse_name(context, principal, &princ_name2) == 0) {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: krb5_kt_get_entry returned %d for principal=%s keytab=%s",
|
||||||
|
ret, princ_name2 ? princ_name2 : "<unparsed>", k->path ? k->path : "<unknown>");
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: krb5_kt_get_entry returned %d for <unparsed principal> keytab=%s",
|
||||||
|
ret, k->path ? k->path : "<unknown>");
|
||||||
|
}
|
||||||
|
free(princ_name2);
|
||||||
ret = HDB_ERR_NOENTRY;
|
ret = HDB_ERR_NOENTRY;
|
||||||
goto out;
|
goto out;
|
||||||
|
} else {
|
||||||
|
/* Success: record what the keytab returned for inspection */
|
||||||
|
{
|
||||||
|
char *entry_princ = NULL;
|
||||||
|
if (krb5_unparse_name(context, ktentry.principal, &entry_princ) == 0) {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: krb5_kt_get_entry succeeded: entry_principal=%s vno=%d enctype=%d keytab=%s",
|
||||||
|
entry_princ ? entry_princ : "<unparsed>",
|
||||||
|
ktentry.vno,
|
||||||
|
ktentry.keyblock.keytype,
|
||||||
|
k->path ? k->path : "<unknown>");
|
||||||
|
} else {
|
||||||
|
krb5_warnx(context, "hkt_fetch_kvno: krb5_kt_get_entry succeeded: entry_principal=<unparsed> vno=%d enctype=%d keytab=%s",
|
||||||
|
ktentry.vno,
|
||||||
|
ktentry.keyblock.keytype,
|
||||||
|
k->path ? k->path : "<unknown>");
|
||||||
|
}
|
||||||
|
free(entry_princ);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_copy_principal(context, principal, &entry->principal);
|
ret = krb5_copy_principal(context, principal, &entry->principal);
|
||||||
|
|||||||
@@ -169,15 +169,12 @@ fuzz_jose_SOURCES = fuzz_jose.c
|
|||||||
fuzz_jose_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/base/libheimbase.la
|
fuzz_jose_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/base/libheimbase.la
|
||||||
fuzz_jose.$(OBJEXT): $(HX509_PROTOS) $(nodist_include_HEADERS)
|
fuzz_jose.$(OBJEXT): $(HX509_PROTOS) $(nodist_include_HEADERS)
|
||||||
test_expr_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/asn1/libasn1.la
|
test_expr_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/asn1/libasn1.la
|
||||||
test_cert_binary_CPPFLAGS = $(AM_CPPFLAGS) -DSRCDIR=\"$(srcdir)\"
|
|
||||||
test_cert_binary_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/asn1/libasn1.la
|
|
||||||
|
|
||||||
TESTS = $(SCRIPT_TESTS) $(PROGRAM_TESTS)
|
TESTS = $(SCRIPT_TESTS) $(PROGRAM_TESTS)
|
||||||
|
|
||||||
PROGRAM_TESTS = \
|
PROGRAM_TESTS = \
|
||||||
test_name \
|
test_name \
|
||||||
test_expr \
|
test_expr
|
||||||
test_cert_binary
|
|
||||||
|
|
||||||
SCRIPT_TESTS = \
|
SCRIPT_TESTS = \
|
||||||
test_ca \
|
test_ca \
|
||||||
@@ -339,7 +336,6 @@ EXTRA_DIST = \
|
|||||||
data/key2.der \
|
data/key2.der \
|
||||||
data/nist-data \
|
data/nist-data \
|
||||||
data/nist-data2 \
|
data/nist-data2 \
|
||||||
data/notafter-2338.pem \
|
|
||||||
data/no-proxy-test.crt \
|
data/no-proxy-test.crt \
|
||||||
data/no-proxy-test.key \
|
data/no-proxy-test.key \
|
||||||
data/ocsp-req1.der \
|
data/ocsp-req1.der \
|
||||||
|
|||||||
+2
-14
@@ -66,18 +66,6 @@ struct hx509_ca_tbs {
|
|||||||
AlgorithmIdentifier *sigalg;
|
AlgorithmIdentifier *sigalg;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
|
||||||
use_utc_time(time_t t)
|
|
||||||
{
|
|
||||||
if (t < 1)
|
|
||||||
return 1;
|
|
||||||
#if SIZEOF_TIME_T > 4 || defined(TIME_T_UNSIGNED)
|
|
||||||
if ((uint64_t)t >= 2524608000ULL)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate an to-be-signed certificate object that will be converted
|
* Allocate an to-be-signed certificate object that will be converted
|
||||||
* into an certificate.
|
* into an certificate.
|
||||||
@@ -1785,13 +1773,13 @@ ca_sign(hx509_context context,
|
|||||||
*
|
*
|
||||||
* Both, ...u.generalTime and ...u..utcTime are time_t.
|
* Both, ...u.generalTime and ...u..utcTime are time_t.
|
||||||
*/
|
*/
|
||||||
if (use_utc_time(notBefore))
|
if (notBefore < 1 || (int64_t)notBefore < 2524608000)
|
||||||
tbsc->validity.notBefore.element = choice_Time_utcTime;
|
tbsc->validity.notBefore.element = choice_Time_utcTime;
|
||||||
else
|
else
|
||||||
tbsc->validity.notBefore.element = choice_Time_generalTime;
|
tbsc->validity.notBefore.element = choice_Time_generalTime;
|
||||||
tbsc->validity.notBefore.u.generalTime = notBefore;
|
tbsc->validity.notBefore.u.generalTime = notBefore;
|
||||||
|
|
||||||
if (use_utc_time(notAfter))
|
if (notAfter < 1 || (int64_t)notAfter < 2524608000)
|
||||||
tbsc->validity.notAfter.element = choice_Time_utcTime;
|
tbsc->validity.notAfter.element = choice_Time_utcTime;
|
||||||
else
|
else
|
||||||
tbsc->validity.notAfter.element = choice_Time_generalTime;
|
tbsc->validity.notAfter.element = choice_Time_generalTime;
|
||||||
|
|||||||
+1
-38
@@ -78,7 +78,6 @@ struct hx509_cert_data {
|
|||||||
unsigned int ref;
|
unsigned int ref;
|
||||||
char *friendlyname;
|
char *friendlyname;
|
||||||
Certificate *data;
|
Certificate *data;
|
||||||
heim_octet_string encoding;
|
|
||||||
hx509_private_key private_key;
|
hx509_private_key private_key;
|
||||||
struct _hx509_cert_attrs attrs;
|
struct _hx509_cert_attrs attrs;
|
||||||
hx509_name basename;
|
hx509_name basename;
|
||||||
@@ -636,8 +635,6 @@ cert_init(hx509_context context, heim_error_t *error)
|
|||||||
cert->release = NULL;
|
cert->release = NULL;
|
||||||
cert->ctx = NULL;
|
cert->ctx = NULL;
|
||||||
cert->data= NULL;
|
cert->data= NULL;
|
||||||
cert->encoding.data = NULL;
|
|
||||||
cert->encoding.length = 0;
|
|
||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,23 +693,7 @@ hx509_cert_copy_no_private_key(hx509_context context,
|
|||||||
hx509_cert src,
|
hx509_cert src,
|
||||||
heim_error_t *error)
|
heim_error_t *error)
|
||||||
{
|
{
|
||||||
hx509_cert cert;
|
return hx509_cert_init(context, src->data, error);
|
||||||
int ret;
|
|
||||||
|
|
||||||
cert = hx509_cert_init(context, src->data, error);
|
|
||||||
if (cert == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret = der_copy_octet_string(&src->encoding, &cert->encoding);
|
|
||||||
if (ret) {
|
|
||||||
hx509_cert_free(cert);
|
|
||||||
if (error)
|
|
||||||
*error = heim_error_create_enomem();
|
|
||||||
errno = ret;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cert;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -766,7 +747,6 @@ hx509_cert_init_data(hx509_context context,
|
|||||||
heim_error_t *error)
|
heim_error_t *error)
|
||||||
{
|
{
|
||||||
hx509_cert cert;
|
hx509_cert cert;
|
||||||
heim_octet_string os;
|
|
||||||
Certificate t;
|
Certificate t;
|
||||||
size_t size;
|
size_t size;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -789,19 +769,6 @@ hx509_cert_init_data(hx509_context context,
|
|||||||
|
|
||||||
cert = hx509_cert_init(context, &t, error);
|
cert = hx509_cert_init(context, &t, error);
|
||||||
free_Certificate(&t);
|
free_Certificate(&t);
|
||||||
if (cert == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
os.length = len;
|
|
||||||
os.data = rk_UNCONST(ptr);
|
|
||||||
ret = der_copy_octet_string(&os, &cert->encoding);
|
|
||||||
if (ret) {
|
|
||||||
hx509_cert_free(cert);
|
|
||||||
if (error)
|
|
||||||
*error = heim_error_create_enomem();
|
|
||||||
errno = ret;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -857,7 +824,6 @@ hx509_cert_free(hx509_cert cert)
|
|||||||
if (cert->data)
|
if (cert->data)
|
||||||
free_Certificate(cert->data);
|
free_Certificate(cert->data);
|
||||||
free(cert->data);
|
free(cert->data);
|
||||||
der_free_octet_string(&cert->encoding);
|
|
||||||
|
|
||||||
for (i = 0; i < cert->attrs.len; i++) {
|
for (i = 0; i < cert->attrs.len; i++) {
|
||||||
der_free_octet_string(&cert->attrs.val[i]->data);
|
der_free_octet_string(&cert->attrs.val[i]->data);
|
||||||
@@ -4091,9 +4057,6 @@ hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os)
|
|||||||
os->data = NULL;
|
os->data = NULL;
|
||||||
os->length = 0;
|
os->length = 0;
|
||||||
|
|
||||||
if (c->encoding.data != NULL)
|
|
||||||
return der_copy_octet_string(&c->encoding, os);
|
|
||||||
|
|
||||||
ASN1_MALLOC_ENCODE(Certificate, os->data, os->length,
|
ASN1_MALLOC_ENCODE(Certificate, os->data, os->length,
|
||||||
_hx509_get_cert(c), &size, ret);
|
_hx509_get_cert(c), &size, ret);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFATCCAumgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAqMRswGQYDVQQDDBJoeDUwOSBUZXN0IFJv
|
|
||||||
b3QgQ0ExCzAJBgNVBAYTAlNFMCAXDTE5MDMyMjIyMjUwMloYDzIzMzgwMTE5MDMxNDA4WjAhMQsw
|
|
||||||
CQYDVQQGEwJTRTESMBAGA1UEAwwJVGVzdCBjZXJ0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
|
||||||
CgKCAgEA2h1NylGd8Z/XpHpF+HWYZrLFfVPeQjV0gc0en/ND16eDf/uizjxEN4BPITam9slRdJ7i
|
|
||||||
m7+t5OtyEWQ2iLOpkWPH7jjE9YwGceUJt+tXXb/bW3IHxSnobzOzoifvH1DwVTNjQSPgsvchd0ur
|
|
||||||
nXMqu7ZOiH985cY3PrYgwVc+bVd47w1H6UHn+rYtMj9CBY1Wr/XEuG6ZGucH1aE/KX3OsjmmqwZ6
|
|
||||||
4iY52JaeO8iveT6aJE5Lsq/kBw5x3C9wJ5c8ovppm1dLxVNeKAywx1cforImD1+/00V4kFos/Gpn
|
|
||||||
M7bBfs0XwFieuoXFFVpaZ9u/LwXNONmUyZV/m2iwYv83ks/Yd77Lcj0PuYBEV8DJEAH9ByUw69hI
|
|
||||||
Ba+Y+sRkbVmmao0b1EvzB5ho47tZySH4EbSighsN6IzgpeEcccrDLZBDw+6ZLH1BSDnIAHINgDkj
|
|
||||||
oTon7QfKMo80yrudZxN9Me1K2zV6zrOJ42SdPkdO07e9qxIWELtm6Bp3TCrguRZpZhSDTkrzb6uF
|
|
||||||
anDGm86Tq3U2o6Wqn0XWon8Xx2/59ec1UaV1xQe+Js57Pyk6dGsXeU7PTAppdVjb66jd8ebMoxhT
|
|
||||||
pcWlWqHPN2qxn9PU6w8CQNKuaM68xUbj7viXiO7IpwF6oSOv8zEsKm8Sd9w8UZ1A9Joqe4UpHz7D
|
|
||||||
1TeObgkCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFBv07DRCuotn
|
|
||||||
rFXyN120aKnYXlh7MA0GCSqGSIb3DQEBBQUAA4ICAQCV9xyZckJP0726P3p1uwE6rc5re7c9XTtG
|
|
||||||
UeqaNpRwNhw7/Lqdiw1ENgitpnOCvCPt+VoJj51iEcGUfGFmH4u5Ctw6tesiVN6j5YqUEB+EUm3+
|
|
||||||
J8jly6WOqYMWlQ1sPleF4eyCBUdtKK0NhPpAoJb0hKrR4Qu3keJHTwWX+BCg6Fe97UhlVXXa5TTo
|
|
||||||
8SCV1kCMQr+02VXIMOjVztgdMGWQOevig+0RA80HwOHEkYSgl45tIuZ1dyF8MotI7dayGS6vJq19
|
|
||||||
bM4J4Xi2cmFgIpK430JrNGtfNe/x08Z/kgU80Ah3AWb3V7hl3tPSsb+TsYyjJ+bU4iubzZ2+MYJb
|
|
||||||
U91avTkFX4xW8n+bt+/mB5a/itmNu2KYht6qkcP+57unH/D9H2ymBATwwlGhkYya7vmHQjd+nCdy
|
|
||||||
WdxgqI7RgZfxFcPYqU6aCemBdjk2swih5V6XN7pDjwYacGk7/nmmXi0mBOm8X1fJ0IDCDUvHDt0E
|
|
||||||
5RVJndf/7qMcBFZ94qDTORpZvYWw61TqgYvhF5Sl/uMM0HRC7kr0ZpBJS2S8RzX1smCOdAXQptKU
|
|
||||||
tOAPSz816irgJFjBbtBlblj34ZACrkAjJemAmtKn6l38bfhFD9tTkVUyRuNqwFQKWkzoGh6mMz7+
|
|
||||||
7batz2o8L7JsR3XxKUMxacMMQlZb2biZe/8rUIc0Lg==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -47,23 +47,6 @@ for a in $srcdir/data/*.crt; do
|
|||||||
${hxtool} print --content FILE:"$a" > /dev/null 2>/dev/null
|
${hxtool} print --content FILE:"$a" > /dev/null 2>/dev/null
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "print certificate with 2338 notAfter"
|
|
||||||
${hxtool} print --content FILE:$srcdir/data/notafter-2338.pem > cert-2338.tmp || exit 1
|
|
||||||
config=$objdir/../../include/config.h
|
|
||||||
if grep '^#define SIZEOF_TIME_T 4$' "$config" > /dev/null; then
|
|
||||||
if grep '^#define TIME_T_UNSIGNED' "$config" > /dev/null; then
|
|
||||||
notafter='notAfter 2106-02-07 06:28:15'
|
|
||||||
else
|
|
||||||
notafter='notAfter 2038-01-19 03:14:07'
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
notafter='notAfter 2338-01-19 03:14:08'
|
|
||||||
fi
|
|
||||||
grep "$notafter" cert-2338.tmp > /dev/null || {
|
|
||||||
cat cert-2338.tmp
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "print NULL"
|
echo "print NULL"
|
||||||
${hxtool} print --content NULL: > /dev/null || exit 1
|
${hxtool} print --content NULL: > /dev/null || exit 1
|
||||||
|
|
||||||
|
|||||||
@@ -1,179 +0,0 @@
|
|||||||
#include "hx_locl.h"
|
|
||||||
#include <err.h>
|
|
||||||
|
|
||||||
#ifndef SRCDIR
|
|
||||||
#define SRCDIR "."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct pem_cert {
|
|
||||||
heim_octet_string der;
|
|
||||||
int found;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
pem_cert_reader(hx509_context context, const char *type,
|
|
||||||
const hx509_pem_header *headers,
|
|
||||||
const void *data, size_t length, void *ctx)
|
|
||||||
{
|
|
||||||
struct pem_cert *pem = ctx;
|
|
||||||
|
|
||||||
(void)context;
|
|
||||||
(void)headers;
|
|
||||||
|
|
||||||
if (strcmp(type, "CERTIFICATE") != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (pem->found)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pem->der.data = malloc(length);
|
|
||||||
if (pem->der.data == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
memcpy(pem->der.data, data, length);
|
|
||||||
pem->der.length = length;
|
|
||||||
pem->found = 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
read_cert_der(hx509_context context, const char *path, heim_octet_string *der)
|
|
||||||
{
|
|
||||||
struct pem_cert pem;
|
|
||||||
FILE *f;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(&pem, 0, sizeof(pem));
|
|
||||||
|
|
||||||
f = fopen(path, "r");
|
|
||||||
if (f == NULL)
|
|
||||||
err(1, "fopen: %s", path);
|
|
||||||
|
|
||||||
ret = hx509_pem_read(context, f, pem_cert_reader, &pem);
|
|
||||||
fclose(f);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_pem_read: %s", path);
|
|
||||||
if (!pem.found)
|
|
||||||
errx(1, "did not find a certificate in %s", path);
|
|
||||||
|
|
||||||
*der = pem.der;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
compare_octet_string(const char *what,
|
|
||||||
const heim_octet_string *expected,
|
|
||||||
const heim_octet_string *actual)
|
|
||||||
{
|
|
||||||
if (actual->length != expected->length)
|
|
||||||
errx(1, "%s length changed from %lu to %lu",
|
|
||||||
what, (unsigned long)expected->length,
|
|
||||||
(unsigned long)actual->length);
|
|
||||||
if (memcmp(actual->data, expected->data, expected->length) != 0)
|
|
||||||
errx(1, "%s data changed", what);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_cert_binary(hx509_context context, const heim_octet_string *der)
|
|
||||||
{
|
|
||||||
heim_octet_string os;
|
|
||||||
hx509_cert cert;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(&os, 0, sizeof(os));
|
|
||||||
|
|
||||||
cert = hx509_cert_init_data(context, der->data, der->length, NULL);
|
|
||||||
if (cert == NULL)
|
|
||||||
err(1, "hx509_cert_init_data");
|
|
||||||
|
|
||||||
ret = hx509_cert_binary(context, cert, &os);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_cert_binary");
|
|
||||||
compare_octet_string("certificate encoding", der, &os);
|
|
||||||
der_free_octet_string(&os);
|
|
||||||
|
|
||||||
hx509_cert_free(cert);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
make_store_name(void)
|
|
||||||
{
|
|
||||||
char *store_name = NULL;
|
|
||||||
|
|
||||||
if (asprintf(&store_name, "FILE:%s/data/test.crt,%s/data/test.key",
|
|
||||||
SRCDIR, SRCDIR) == -1 || store_name == NULL)
|
|
||||||
err(1, "asprintf");
|
|
||||||
|
|
||||||
return store_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_keyless_store_cert_encoding(hx509_context context,
|
|
||||||
const heim_octet_string *der)
|
|
||||||
{
|
|
||||||
heim_octet_string os;
|
|
||||||
hx509_certs certs = NULL;
|
|
||||||
hx509_cert cert = NULL;
|
|
||||||
char *store_name;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(&os, 0, sizeof(os));
|
|
||||||
|
|
||||||
ret = hx509_certs_init(context, "MEMORY:test-keyless-certs",
|
|
||||||
HX509_CERTS_NO_PRIVATE_KEYS, NULL, &certs);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_certs_init");
|
|
||||||
|
|
||||||
store_name = make_store_name();
|
|
||||||
ret = hx509_certs_append(context, certs, NULL, store_name);
|
|
||||||
free(store_name);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_certs_append");
|
|
||||||
|
|
||||||
ret = hx509_get_one_cert(context, certs, &cert);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_get_one_cert");
|
|
||||||
if (hx509_cert_have_private_key(cert))
|
|
||||||
errx(1, "HX509_CERTS_NO_PRIVATE_KEYS store kept a private key");
|
|
||||||
|
|
||||||
ret = hx509_cert_binary(context, cert, &os);
|
|
||||||
if (ret)
|
|
||||||
hx509_err(context, 1, ret, "hx509_cert_binary on keyless cert");
|
|
||||||
compare_octet_string("keyless store certificate encoding", der, &os);
|
|
||||||
|
|
||||||
der_free_octet_string(&os);
|
|
||||||
hx509_cert_free(cert);
|
|
||||||
hx509_certs_free(&certs);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
heim_octet_string der;
|
|
||||||
hx509_context context;
|
|
||||||
char *cert_path = NULL;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
|
|
||||||
memset(&der, 0, sizeof(der));
|
|
||||||
|
|
||||||
ret = hx509_context_init(&context);
|
|
||||||
if (ret)
|
|
||||||
errx(1, "hx509_context_init failed with %d", ret);
|
|
||||||
|
|
||||||
if (asprintf(&cert_path, "%s/data/test.crt", SRCDIR) == -1 ||
|
|
||||||
cert_path == NULL)
|
|
||||||
err(1, "asprintf");
|
|
||||||
|
|
||||||
read_cert_der(context, cert_path, &der);
|
|
||||||
free(cert_path);
|
|
||||||
|
|
||||||
check_cert_binary(context, &der);
|
|
||||||
check_keyless_store_cert_encoding(context, &der);
|
|
||||||
|
|
||||||
der_free_octet_string(&der);
|
|
||||||
hx509_context_free(&context);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+3
-13
@@ -46,23 +46,14 @@ if have_gcd
|
|||||||
# stops building on recent OS X releases unless we disable this warning.
|
# stops building on recent OS X releases unless we disable this warning.
|
||||||
WFLAGS += -Wno-deprecated-declarations
|
WFLAGS += -Wno-deprecated-declarations
|
||||||
|
|
||||||
heim_ipc.stamp: heim_ipc.defs
|
heim_ipc.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.defs
|
||||||
mig -header heim_ipc.h -user heim_ipcUser.c -sheader heim_ipcServer.h -server heim_ipcServer.c -I$(srcdir) $(srcdir)/heim_ipc.defs
|
mig -header heim_ipc.h -user heim_ipcUser.c -sheader heim_ipcServer.h -server heim_ipcServer.c -I$(srcdir) $(srcdir)/heim_ipc.defs
|
||||||
touch $@
|
|
||||||
|
|
||||||
heim_ipc.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.stamp
|
heim_ipc_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.defs
|
||||||
|
|
||||||
heim_ipc_async.stamp: heim_ipc_async.defs
|
|
||||||
mig -header heim_ipc_async.h -user heim_ipc_asyncUser.c -sheader heim_ipc_asyncServer.h -server heim_ipc_asyncServer.c -I$(srcdir) $(srcdir)/heim_ipc_async.defs
|
mig -header heim_ipc_async.h -user heim_ipc_asyncUser.c -sheader heim_ipc_asyncServer.h -server heim_ipc_asyncServer.c -I$(srcdir) $(srcdir)/heim_ipc_async.defs
|
||||||
touch $@
|
|
||||||
|
|
||||||
heim_ipc_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.stamp
|
heim_ipc_reply.h heim_ipc_replyUser.c: heim_ipc_reply.defs
|
||||||
|
|
||||||
heim_ipc_reply.stamp: heim_ipc_reply.defs
|
|
||||||
mig -header heim_ipc_reply.h -user heim_ipc_replyUser.c -sheader /dev/null -server /dev/null -I$(srcdir) $(srcdir)/heim_ipc_reply.defs
|
mig -header heim_ipc_reply.h -user heim_ipc_replyUser.c -sheader /dev/null -server /dev/null -I$(srcdir) $(srcdir)/heim_ipc_reply.defs
|
||||||
touch $@
|
|
||||||
|
|
||||||
heim_ipc_reply.h heim_ipc_replyUser.c: heim_ipc_reply.stamp
|
|
||||||
|
|
||||||
built_ipcc = heim_ipc.h heim_ipcUser.c
|
built_ipcc = heim_ipc.h heim_ipcUser.c
|
||||||
built_ipcc += heim_ipc_asyncServer.c heim_ipc_asyncServer.h
|
built_ipcc += heim_ipc_asyncServer.c heim_ipc_asyncServer.h
|
||||||
@@ -78,7 +69,6 @@ nodist_libheim_ipcs_la_SOURCES = $(built_ipcs)
|
|||||||
libheim_ipcs_la_LIBADD += -lbsm
|
libheim_ipcs_la_LIBADD += -lbsm
|
||||||
|
|
||||||
CLEANFILES = $(built_ipcc) $(built_ipcs)
|
CLEANFILES = $(built_ipcc) $(built_ipcs)
|
||||||
CLEANFILES += heim_ipc.stamp heim_ipc_async.stamp heim_ipc_reply.stamp
|
|
||||||
|
|
||||||
$(srcdir)/client.c: $(built_ipcc)
|
$(srcdir)/client.c: $(built_ipcc)
|
||||||
$(srcdir)/server.c: $(built_ipcs)
|
$(srcdir)/server.c: $(built_ipcs)
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
@@ -53,17 +53,6 @@
|
|||||||
#define LOG_VERSION_FIRST 1
|
#define LOG_VERSION_FIRST 1
|
||||||
#define LOG_VERSION_UBER 0
|
#define LOG_VERSION_UBER 0
|
||||||
|
|
||||||
#define LOG_HEADER_SZ ((off_t)(sizeof(uint32_t) * 4))
|
|
||||||
#define LOG_TRAILER_SZ ((off_t)(sizeof(uint32_t) * 2))
|
|
||||||
#define LOG_WRAPPER_SZ ((off_t)(LOG_HEADER_SZ + LOG_TRAILER_SZ))
|
|
||||||
#define LOG_UBER_LEN ((off_t)(sizeof(uint64_t) + sizeof(uint32_t) * 2))
|
|
||||||
#define LOG_UBER_SZ ((off_t)(LOG_WRAPPER_SZ + LOG_UBER_LEN))
|
|
||||||
|
|
||||||
struct kadm5_log_snap {
|
|
||||||
char bytes;
|
|
||||||
char buf[LOG_UBER_SZ + LOG_HEADER_SZ];
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <krb5.h>
|
#include <krb5.h>
|
||||||
|
|
||||||
#define KRB5_KDB_DISALLOW_POSTDATED 0x00000001
|
#define KRB5_KDB_DISALLOW_POSTDATED 0x00000001
|
||||||
|
|||||||
+153
-21
@@ -191,6 +191,20 @@ _kadm5_c_init_context(kadm5_client_context **ctx,
|
|||||||
}
|
}
|
||||||
if ((*ctx)->readonly_kadmind_port == 0)
|
if ((*ctx)->readonly_kadmind_port == 0)
|
||||||
(*ctx)->readonly_kadmind_port = (*ctx)->kadmind_port;
|
(*ctx)->readonly_kadmind_port = (*ctx)->kadmind_port;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: emit context-level info to help trace client init-time
|
||||||
|
* decisions in test logs.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context,
|
||||||
|
"_kadm5_c_init_context: realm=%s admin_server=%s readonly_admin_server=%s kadmind_port=%u readonly_port=%u (pid=%d)",
|
||||||
|
(*ctx)->realm ? (*ctx)->realm : "<null>",
|
||||||
|
(*ctx)->admin_server ? (*ctx)->admin_server : "<null>",
|
||||||
|
(*ctx)->readonly_admin_server ? (*ctx)->readonly_admin_server : "<null>",
|
||||||
|
(unsigned)ntohs((*ctx)->kadmind_port),
|
||||||
|
(unsigned)ntohs((*ctx)->readonly_kadmind_port),
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,10 +217,12 @@ kadm5_c_dup_context(void *vin, void **out)
|
|||||||
kadm5_client_context *ctx;
|
kadm5_client_context *ctx;
|
||||||
|
|
||||||
*out = NULL;
|
*out = NULL;
|
||||||
ctx = calloc(1, sizeof(*ctx));
|
ctx = malloc(sizeof(*ctx));
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return krb5_enomem(in->context);
|
return krb5_enomem(in->context);
|
||||||
|
|
||||||
|
|
||||||
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
set_funcs(ctx);
|
set_funcs(ctx);
|
||||||
ctx->readonly_kadmind_port = in->readonly_kadmind_port;
|
ctx->readonly_kadmind_port = in->readonly_kadmind_port;
|
||||||
ctx->kadmind_port = in->kadmind_port;
|
ctx->kadmind_port = in->kadmind_port;
|
||||||
@@ -224,13 +240,18 @@ kadm5_c_dup_context(void *vin, void **out)
|
|||||||
if (in->readonly_admin_server &&
|
if (in->readonly_admin_server &&
|
||||||
(ctx->readonly_admin_server = strdup(in->readonly_admin_server)) == NULL)
|
(ctx->readonly_admin_server = strdup(in->readonly_admin_server)) == NULL)
|
||||||
ret = krb5_enomem(context);
|
ret = krb5_enomem(context);
|
||||||
if (in->client_name != NULL &&
|
|
||||||
(ctx->client_name = strdup(in->client_name)) == NULL)
|
/* Preserve client identity and prompter behavior in duplicated context */
|
||||||
|
if (in->client_name && (ctx->client_name = strdup(in->client_name)) == NULL)
|
||||||
ret = krb5_enomem(context);
|
ret = krb5_enomem(context);
|
||||||
if (in->keytab && (ctx->keytab = strdup(in->keytab)) == NULL)
|
if (in->service_name && (ctx->service_name = strdup(in->service_name)) == NULL)
|
||||||
ret = krb5_enomem(context);
|
ret = krb5_enomem(context);
|
||||||
|
/* Copy the prompter pointer so duplicated contexts behave the same
|
||||||
|
with respect to prompting vs keytab-based auth. */
|
||||||
ctx->prompter = in->prompter;
|
ctx->prompter = in->prompter;
|
||||||
|
|
||||||
|
if (in->keytab && (ctx->keytab = strdup(in->keytab)) == NULL)
|
||||||
|
ret = krb5_enomem(context);
|
||||||
if (in->ccache) {
|
if (in->ccache) {
|
||||||
char *fullname = NULL;
|
char *fullname = NULL;
|
||||||
|
|
||||||
@@ -295,7 +316,24 @@ get_new_cache(krb5_context context,
|
|||||||
krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
|
krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
|
||||||
krb5_get_init_creds_opt_set_proxiable (opt, FALSE);
|
krb5_get_init_creds_opt_set_proxiable (opt, FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: record the inputs to credential selection so tests can
|
||||||
|
* observe why keytab vs password paths were chosen.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context,
|
||||||
|
"get_new_cache: entry client=%s password_provided=%d prompter=%p keytab=%s server_name=%s (pid=%d)",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>",
|
||||||
|
password ? 1 : 0,
|
||||||
|
(void *)prompter,
|
||||||
|
keytab ? keytab : "<default>",
|
||||||
|
server_name ? server_name : "<null>",
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
if(password == NULL && prompter == NULL) {
|
if(password == NULL && prompter == NULL) {
|
||||||
|
/* Debug: choosing keytab-based initial credentials */
|
||||||
|
krb5_warnx(context, "get_new_cache: choosing keytab auth (keytab=%s, client=%s)",
|
||||||
|
keytab ? keytab : "<default>",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
krb5_keytab kt;
|
krb5_keytab kt;
|
||||||
if(keytab == NULL)
|
if(keytab == NULL)
|
||||||
ret = krb5_kt_default(context, &kt);
|
ret = krb5_kt_default(context, &kt);
|
||||||
@@ -312,8 +350,21 @@ get_new_cache(krb5_context context,
|
|||||||
0,
|
0,
|
||||||
server_name,
|
server_name,
|
||||||
opt);
|
opt);
|
||||||
|
/* Log success/failure of keytab credential attempt for diagnostics */
|
||||||
|
if (ret == 0) {
|
||||||
|
krb5_warnx(context, "get_new_cache: krb5_get_init_creds_keytab succeeded for principal=%s using keytab=%s",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>",
|
||||||
|
keytab ? keytab : "<default>");
|
||||||
|
} else {
|
||||||
|
krb5_warn(context, ret, "get_new_cache: krb5_get_init_creds_keytab failed (keytab=%s)", keytab ? keytab : "<default>");
|
||||||
|
}
|
||||||
krb5_kt_close(context, kt);
|
krb5_kt_close(context, kt);
|
||||||
} else {
|
} else {
|
||||||
|
/* Debug: choosing password-based initial credentials */
|
||||||
|
krb5_warnx(context, "get_new_cache: choosing password auth (password_provided=%d prompter=%p client=%s)",
|
||||||
|
password ? 1 : 0,
|
||||||
|
(void *)prompter,
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
ret = krb5_get_init_creds_password (context,
|
ret = krb5_get_init_creds_password (context,
|
||||||
&cred,
|
&cred,
|
||||||
client,
|
client,
|
||||||
@@ -323,6 +374,13 @@ get_new_cache(krb5_context context,
|
|||||||
0,
|
0,
|
||||||
server_name,
|
server_name,
|
||||||
opt);
|
opt);
|
||||||
|
if (ret == 0) {
|
||||||
|
krb5_warnx(context, "get_new_cache: krb5_get_init_creds_password succeeded for principal=%s",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
|
} else {
|
||||||
|
krb5_warn(context, ret, "get_new_cache: krb5_get_init_creds_password failed for principal=%s",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
krb5_get_init_creds_opt_free(context, opt);
|
krb5_get_init_creds_opt_free(context, opt);
|
||||||
switch(ret){
|
switch(ret){
|
||||||
@@ -451,6 +509,27 @@ _kadm5_c_get_cred_cache(krb5_context context,
|
|||||||
if(server_name == NULL)
|
if(server_name == NULL)
|
||||||
server_name = KADM5_ADMIN_SERVICE;
|
server_name = KADM5_ADMIN_SERVICE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: log the invocation and environment so we can correlate
|
||||||
|
* with test harness behavior (e.g. whether KRB5_KTNAME / KRB5CCNAME
|
||||||
|
* were set).
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
const char *env_kt = secure_getenv ? secure_getenv("KRB5_KTNAME") : getenv("KRB5_KTNAME");
|
||||||
|
const char *env_cc = secure_getenv ? secure_getenv("KRB5CCNAME") : getenv("KRB5CCNAME");
|
||||||
|
krb5_warnx(context,
|
||||||
|
"_kadm5_c_get_cred_cache: called client_name=%s server_name=%s password_provided=%d prompter=%p keytab=%s ccache=%p env.KRB5_KTNAME=%s env.KRB5CCNAME=%s (pid=%d)",
|
||||||
|
client_name ? client_name : "<null>",
|
||||||
|
server_name ? server_name : "<null>",
|
||||||
|
password ? 1 : 0,
|
||||||
|
(void *)prompter,
|
||||||
|
keytab ? keytab : "<null>",
|
||||||
|
(void *)ccache,
|
||||||
|
env_kt ? env_kt : "<unset>",
|
||||||
|
env_cc ? env_cc : "<unset>",
|
||||||
|
(int)getpid());
|
||||||
|
}
|
||||||
|
|
||||||
if(client_name != NULL) {
|
if(client_name != NULL) {
|
||||||
ret = krb5_parse_name(context, client_name, &client);
|
ret = krb5_parse_name(context, client_name, &client);
|
||||||
if(ret)
|
if(ret)
|
||||||
@@ -458,19 +537,9 @@ _kadm5_c_get_cred_cache(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ccache != NULL) {
|
if(ccache != NULL) {
|
||||||
char *fullname = NULL;
|
id = ccache;
|
||||||
|
ret = krb5_cc_get_principal(context, id, &client);
|
||||||
ret = krb5_cc_get_full_name(context, ccache, &fullname);
|
if(ret)
|
||||||
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);
|
|
||||||
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,26 +584,47 @@ _kadm5_c_get_cred_cache(krb5_context context,
|
|||||||
|
|
||||||
if(id && client && (default_client == NULL ||
|
if(id && client && (default_client == NULL ||
|
||||||
krb5_principal_compare(context, client, default_client) != 0)) {
|
krb5_principal_compare(context, client, default_client) != 0)) {
|
||||||
|
/* Debug: attempting to obtain kadmin ticket from existing credential cache */
|
||||||
|
krb5_warnx(context, "_kadm5_c_get_cred_cache: trying credential cache to get kadmin ticket (client=%s)",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
ret = get_kadm_ticket(context, id, client, server_name);
|
ret = get_kadm_ticket(context, id, client, server_name);
|
||||||
if(ret == 0) {
|
if(ret == 0) {
|
||||||
|
krb5_warnx(context, "_kadm5_c_get_cred_cache: got kadmin ticket from cache for client=%s",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
*ret_cache = id;
|
*ret_cache = id;
|
||||||
krb5_free_principal(context, default_client);
|
krb5_free_principal(context, default_client);
|
||||||
if (default_client != client)
|
if (default_client != client)
|
||||||
krb5_free_principal(context, client);
|
krb5_free_principal(context, client);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
krb5_warn(context, ret, "_kadm5_c_get_cred_cache: get_kadm_ticket from cache failed for client=%s", client ? krb5_principal_get_comp_string(context, client, 0) : "<null>");
|
||||||
if(ccache != NULL)
|
if(ccache != NULL)
|
||||||
/* couldn't get ticket from cache */
|
/* couldn't get ticket from cache */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* get creds via AS request */
|
/* get creds via AS request */
|
||||||
if (id)
|
if(id && (id != ccache))
|
||||||
krb5_cc_close(context, id);
|
krb5_cc_close(context, id);
|
||||||
if (client != default_client)
|
if (client != default_client)
|
||||||
krb5_free_principal(context, default_client);
|
krb5_free_principal(context, default_client);
|
||||||
|
|
||||||
ret = get_new_cache(context, client, password, prompter, keytab,
|
ret = get_new_cache(context, client, password, prompter, keytab,
|
||||||
server_name, ret_cache);
|
server_name, ret_cache);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: report the result of get_new_cache so caller logs
|
||||||
|
* can show why auth succeeded/failed.
|
||||||
|
*/
|
||||||
|
if (ret == 0) {
|
||||||
|
krb5_warnx(context, "_kadm5_c_get_cred_cache: get_new_cache succeeded for client=%s (pid=%d)",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>",
|
||||||
|
(int)getpid());
|
||||||
|
} else {
|
||||||
|
krb5_warn(context, ret, "_kadm5_c_get_cred_cache: get_new_cache failed for client=%s (pid=%d)",
|
||||||
|
client ? krb5_principal_get_comp_string(context, client, 0) : "<null>",
|
||||||
|
(int)getpid());
|
||||||
|
}
|
||||||
|
|
||||||
krb5_free_principal(context, client);
|
krb5_free_principal(context, client);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -558,6 +648,17 @@ kadm_connect(kadm5_client_context *ctx)
|
|||||||
krb5_context context = ctx->context;
|
krb5_context context = ctx->context;
|
||||||
int writable = 0;
|
int writable = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: record connect intent and client context pointers
|
||||||
|
* to help correlate kadmin network activity with credential selection.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context, "kadm_connect: entering (client_name=%s prompter=%p keytab=%s ccache=%p pid=%d)",
|
||||||
|
ctx->client_name ? ctx->client_name : "<null>",
|
||||||
|
(void *)ctx->prompter,
|
||||||
|
ctx->keytab ? ctx->keytab : "<null>",
|
||||||
|
(void *)ctx->ccache,
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
if (ctx->ac)
|
if (ctx->ac)
|
||||||
krb5_auth_con_free(context, ctx->ac);
|
krb5_auth_con_free(context, ctx->ac);
|
||||||
ctx->ac = NULL;
|
ctx->ac = NULL;
|
||||||
@@ -671,6 +772,12 @@ out:
|
|||||||
rk_closesocket(s);
|
rk_closesocket(s);
|
||||||
krb5_auth_con_free(context, ctx->ac);
|
krb5_auth_con_free(context, ctx->ac);
|
||||||
ctx->ac = NULL;
|
ctx->ac = NULL;
|
||||||
|
} else {
|
||||||
|
/* Extra debug: successful connect and auth */
|
||||||
|
krb5_warnx(context, "kadm_connect: success connected_to_writable=%d sock=%d (pid=%d)",
|
||||||
|
(int)ctx->connected_to_writable,
|
||||||
|
(int)ctx->sock,
|
||||||
|
(int)getpid());
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -717,12 +824,25 @@ kadm5_c_init_with_context(krb5_context context,
|
|||||||
kadm5_client_context *ctx = NULL;
|
kadm5_client_context *ctx = NULL;
|
||||||
krb5_ccache cc;
|
krb5_ccache cc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: record initialization flags and pointers so we can later
|
||||||
|
* understand whether a prompter was provided (which affects keytab vs
|
||||||
|
* password selection) and whether a keytab or ccache was requested.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context, "kadm5_c_init_with_context: client_name=%s password_provided=%d prompter=%p keytab=%s ccache=%p service_name=%s (pid=%d)",
|
||||||
|
client_name ? client_name : "<null>",
|
||||||
|
password ? 1 : 0,
|
||||||
|
(void *)prompter,
|
||||||
|
keytab ? keytab : "<null>",
|
||||||
|
(void *)ccache,
|
||||||
|
service_name ? service_name : "<null>",
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
ret = _kadm5_c_init_context(&ctx, realm_params, context);
|
ret = _kadm5_c_init_context(&ctx, realm_params, context);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((password != NULL && *password != '\0') ||
|
if (password != NULL && *password != '\0') {
|
||||||
(client_name && !keytab)) {
|
|
||||||
ret = _kadm5_c_get_cred_cache(context,
|
ret = _kadm5_c_get_cred_cache(context,
|
||||||
client_name,
|
client_name,
|
||||||
service_name,
|
service_name,
|
||||||
@@ -750,6 +870,19 @@ kadm5_c_init_with_context(krb5_context context,
|
|||||||
ctx->sock = -1;
|
ctx->sock = -1;
|
||||||
|
|
||||||
*server_handle = ctx;
|
*server_handle = ctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra debug: final context values after init so logs show what the
|
||||||
|
* kadm client will carry into subsequent connect attempts.
|
||||||
|
*/
|
||||||
|
krb5_warnx(context, "kadm5_c_init_with_context: done ctx=%p client_name=%s prompter=%p keytab=%s ccache=%p (pid=%d)",
|
||||||
|
(void *)ctx,
|
||||||
|
ctx->client_name ? ctx->client_name : "<null>",
|
||||||
|
(void *)ctx->prompter,
|
||||||
|
ctx->keytab ? ctx->keytab : "<null>",
|
||||||
|
(void *)ctx->ccache,
|
||||||
|
(int)getpid());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,4 +1069,3 @@ kadm5_init(char *client_name, char *pass,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+176
-285
@@ -86,46 +86,37 @@ make_signal_socket (krb5_context context)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
listen_port(krb5_context context, const char *port_str)
|
|
||||||
{
|
|
||||||
int port;
|
|
||||||
|
|
||||||
if (port_str) {
|
|
||||||
port = krb5_getportbyname(context, port_str, "tcp", 0);
|
|
||||||
if (port == 0) {
|
|
||||||
char *ptr;
|
|
||||||
long num;
|
|
||||||
|
|
||||||
num = strtol(port_str, &ptr, 10);
|
|
||||||
if (num == 0 && ptr == port_str)
|
|
||||||
krb5_errx(context, 1, "bad port `%s'", port_str);
|
|
||||||
port = htons(num);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
port = krb5_getportbyname(context, IPROP_SERVICE,
|
|
||||||
"tcp", IPROP_PORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
static krb5_socket_t
|
static krb5_socket_t
|
||||||
make_listen_socket(krb5_context context, int port)
|
make_listen_socket (krb5_context context, const char *port_str)
|
||||||
{
|
{
|
||||||
krb5_socket_t fd;
|
krb5_socket_t fd;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
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)
|
||||||
@@ -133,68 +124,15 @@ make_listen_socket(krb5_context context, int port)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AF_INET6
|
|
||||||
static krb5_socket_t
|
|
||||||
make_listen_socket6(krb5_context context, int port)
|
|
||||||
{
|
|
||||||
krb5_socket_t fd;
|
|
||||||
int one = 1;
|
|
||||||
struct sockaddr_in6 addr;
|
|
||||||
|
|
||||||
fd = socket(AF_INET6, SOCK_STREAM, 0);
|
|
||||||
if (rk_IS_BAD_SOCKET(fd)) {
|
|
||||||
#ifdef EAFNOSUPPORT
|
|
||||||
if (rk_SOCK_ERRNO != EAFNOSUPPORT)
|
|
||||||
#endif
|
|
||||||
krb5_warn(context, rk_SOCK_ERRNO, "socket AF_INET6");
|
|
||||||
return rk_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
(void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
|
|
||||||
socket_set_ipv6only(fd, 1);
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sin6_family = AF_INET6;
|
|
||||||
addr.sin6_port = port;
|
|
||||||
addr.sin6_addr = in6addr_any;
|
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
|
||||||
krb5_warn(context, errno, "bind AF_INET6");
|
|
||||||
rk_closesocket(fd);
|
|
||||||
return rk_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
if (listen(fd, SOMAXCONN) < 0) {
|
|
||||||
krb5_warn (context, errno, "listen AF_INET6");
|
|
||||||
rk_closesocket(fd);
|
|
||||||
return rk_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
make_listen_sockets(krb5_context context, const char *port_str,
|
|
||||||
krb5_socket_t *fds, int *num_fds)
|
|
||||||
{
|
|
||||||
krb5_socket_t fd;
|
|
||||||
int port = listen_port(context, port_str);
|
|
||||||
|
|
||||||
*num_fds = 0;
|
|
||||||
|
|
||||||
#ifdef AF_INET6
|
|
||||||
fd = make_listen_socket6(context, port);
|
|
||||||
if (!rk_IS_BAD_SOCKET(fd))
|
|
||||||
fds[(*num_fds)++] = fd;
|
|
||||||
#endif
|
|
||||||
fds[(*num_fds)++] = make_listen_socket(context, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct slave {
|
struct slave {
|
||||||
krb5_socket_t fd;
|
krb5_socket_t fd;
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_in addr;
|
||||||
char *name;
|
char *name;
|
||||||
krb5_auth_context ac;
|
krb5_auth_context ac;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t version_tstamp;
|
uint32_t version_tstamp;
|
||||||
|
uint32_t version_ack;
|
||||||
time_t seen;
|
time_t seen;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
#define SLAVE_F_DEAD 0x1
|
#define SLAVE_F_DEAD 0x1
|
||||||
@@ -438,6 +376,7 @@ add_slave (krb5_context context, krb5_keytab keytab, slave **root,
|
|||||||
krb5_warnx (context, "connection from %s", s->name);
|
krb5_warnx (context, "connection from %s", s->name);
|
||||||
|
|
||||||
s->version = 0;
|
s->version = 0;
|
||||||
|
s->version_ack = 0;
|
||||||
s->flags = 0;
|
s->flags = 0;
|
||||||
slave_seen(s);
|
slave_seen(s);
|
||||||
s->next = *root;
|
s->next = *root;
|
||||||
@@ -923,11 +862,8 @@ diffready(krb5_context context, slave *s)
|
|||||||
* Don't send any diffs until slave has sent an I_HAVE telling us the
|
* Don't send any diffs until slave has sent an I_HAVE telling us the
|
||||||
* initial version number!
|
* initial version number!
|
||||||
*/
|
*/
|
||||||
if ((s->flags & SLAVE_F_READY) == 0) {
|
if ((s->flags & SLAVE_F_READY) == 0)
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "not sending diffs to not-ready slave %s", s->name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (s->flags & SLAVE_F_DEAD) {
|
if (s->flags & SLAVE_F_DEAD) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -936,11 +872,8 @@ diffready(krb5_context context, slave *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write any remainder of previous write, if we can. */
|
/* Write any remainder of previous write, if we can. */
|
||||||
if (send_tail(context, s) != 0 && have_tail(s)) {
|
if (send_tail(context, s) != 0)
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "not sending diffs to busy slave %s", s->name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -948,6 +881,10 @@ diffready(krb5_context context, slave *s)
|
|||||||
static int
|
static int
|
||||||
nodiffs(krb5_context context, slave *s, uint32_t current_version)
|
nodiffs(krb5_context context, slave *s, uint32_t current_version)
|
||||||
{
|
{
|
||||||
|
krb5_storage *sp;
|
||||||
|
krb5_data data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (s->version < current_version)
|
if (s->version < current_version)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -960,20 +897,6 @@ nodiffs(krb5_context context, slave *s, uint32_t current_version)
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "slave %s version %ld already sent", s->name,
|
krb5_warnx(context, "slave %s version %ld already sent", s->name,
|
||||||
(long)s->version);
|
(long)s->version);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
send_you_have_last_version(krb5_context context, slave *s)
|
|
||||||
{
|
|
||||||
krb5_storage *sp;
|
|
||||||
krb5_data data;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "slave %s version %ld is latest", s->name,
|
|
||||||
(long)s->version);
|
|
||||||
|
|
||||||
sp = krb5_storage_emem();
|
sp = krb5_storage_emem();
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
krb5_errx(context, IPROPD_RESTART, "krb5_storage_from_mem");
|
krb5_errx(context, IPROPD_RESTART, "krb5_storage_from_mem");
|
||||||
@@ -986,17 +909,19 @@ send_you_have_last_version(krb5_context context, slave *s)
|
|||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = mk_priv_tail(context, s, &data);
|
ret = mk_priv_tail(context, s, &data);
|
||||||
if (ret)
|
|
||||||
krb5_err(context, IPROPD_RESTART, ret,
|
|
||||||
"sending you have last version");
|
|
||||||
krb5_data_free(&data);
|
krb5_data_free(&data);
|
||||||
}
|
}
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
send_tail(context, s);
|
send_tail(context, s);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock the log and return initial version and timestamp
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
get_first(kadm5_server_context *server_context,
|
get_first(kadm5_server_context *server_context, int log_fd,
|
||||||
uint32_t *initial_verp, uint32_t *initial_timep)
|
uint32_t *initial_verp, uint32_t *initial_timep)
|
||||||
{
|
{
|
||||||
krb5_context context = server_context->context;
|
krb5_context context = server_context->context;
|
||||||
@@ -1006,14 +931,19 @@ get_first(kadm5_server_context *server_context,
|
|||||||
* We don't want to perform tight retry loops on log access errors, so on
|
* We don't want to perform tight retry loops on log access errors, so on
|
||||||
* error mark the slave dead. The slave reconnect after a delay...
|
* error mark the slave dead. The slave reconnect after a delay...
|
||||||
*/
|
*/
|
||||||
|
if (flock(log_fd, LOCK_SH) == -1) {
|
||||||
|
krb5_warn(context, errno, "could not obtain shared lock on log file");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_FIRST,
|
ret = kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_FIRST,
|
||||||
initial_verp, initial_timep);
|
initial_verp, initial_timep);
|
||||||
if (ret == HEIM_ERR_EOF || ret == KADM5_LOG_EMPTY)
|
if (ret == HEIM_ERR_EOF)
|
||||||
ret = kadm5_log_get_version_fd(server_context, -1,
|
ret = kadm5_log_get_version_fd(server_context, log_fd,
|
||||||
LOG_VERSION_UBER, initial_verp,
|
LOG_VERSION_UBER, initial_verp,
|
||||||
initial_timep);
|
initial_timep);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
krb5_warn(context, ret, "could not read initial log entry");
|
krb5_warn(context, ret, "could not read initial log entry");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1024,20 +954,17 @@ get_first(kadm5_server_context *server_context,
|
|||||||
/*-
|
/*-
|
||||||
* Find the left end of the diffs in the log we want to send.
|
* Find the left end of the diffs in the log we want to send.
|
||||||
*
|
*
|
||||||
* - On success, return a positive offset to the first new entry.
|
* - On success, return a positive offset to the first new entry, retaining
|
||||||
* - On error, return a negative offset.
|
* a read lock on the log file.
|
||||||
|
* - On error, return a negative offset, with the lock released.
|
||||||
* - If we simply find no successor entry in the log, return zero
|
* - If we simply find no successor entry in the log, return zero
|
||||||
* with the lock released, which indicates that fallback to send_complete()
|
* with the lock released, which indicates that fallback to send_complete()
|
||||||
* is needed.
|
* is needed.
|
||||||
*
|
|
||||||
* The caller must use kadm5_log_snapshot()/kadm5_log_snapshot_verify() to
|
|
||||||
* ensure that the data read here is consistent because there have been only
|
|
||||||
* append writes and/or there have been no log rotations.
|
|
||||||
*/
|
*/
|
||||||
static off_t
|
static off_t
|
||||||
get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
||||||
uint32_t current_version, uint32_t *initial_verp,
|
int log_fd, uint32_t current_version,
|
||||||
uint32_t *initial_timep)
|
uint32_t *initial_verp, uint32_t *initial_timep)
|
||||||
{
|
{
|
||||||
krb5_context context = server_context->context;
|
krb5_context context = server_context->context;
|
||||||
off_t pos;
|
off_t pos;
|
||||||
@@ -1047,13 +974,17 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
uint32_t ver = s->version;
|
uint32_t ver = s->version;
|
||||||
|
|
||||||
ret = get_first(server_context, initial_verp, initial_timep);
|
/* This acquires a read lock on success */
|
||||||
|
ret = get_first(server_context, log_fd,
|
||||||
|
initial_verp, initial_timep);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* When the slave version is out of range, send the whole database. */
|
/* When the slave version is out of range, send the whole database. */
|
||||||
if (ver == 0 || ver + 1 < *initial_verp || ver > current_version)
|
if (ver == 0 || ver < *initial_verp || ver > current_version) {
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Avoid seeking past the last committed record */
|
/* Avoid seeking past the last committed record */
|
||||||
if (kadm5_log_goto_end(server_context, sp) != 0 ||
|
if (kadm5_log_goto_end(server_context, sp) != 0 ||
|
||||||
@@ -1085,12 +1016,13 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Slow path: seek backwards, entry by entry, from the end.
|
* Drop the lock and try to find the left entry by seeking backward
|
||||||
*
|
* from the end of the end of the log. If we succeed, re-acquire the
|
||||||
* Try to find the left entry by seeking backward from the end of the
|
* lock, update "next_diff", and retry the fast-path.
|
||||||
* end of the log. If we succeed, update "next_diff", and retry the
|
|
||||||
* fast-path.
|
|
||||||
*/
|
*/
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
|
|
||||||
|
/* Slow path: seek backwards, entry by entry, from the end */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
enum kadm_ops op;
|
enum kadm_ops op;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
@@ -1106,7 +1038,7 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't expect to reach the slave's version, unless the log
|
* We don't expect to reach the slave's version, unless the log
|
||||||
* has been rotated.
|
* has been modified after we released the lock.
|
||||||
*/
|
*/
|
||||||
if (ver == s->version) {
|
if (ver == s->version) {
|
||||||
krb5_warnx(context, "iprop log truncated while sending diffs "
|
krb5_warnx(context, "iprop log truncated while sending diffs "
|
||||||
@@ -1128,28 +1060,33 @@ get_left(kadm5_server_context *server_context, slave *s, krb5_storage *sp,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If we loop then we're hoping to hit the fast path so we can return a
|
* If we loop then we're hoping to hit the fast path so we can return a
|
||||||
* non-zero, positive left offset.
|
* non-zero, positive left offset with the lock held.
|
||||||
*
|
*
|
||||||
* We just updated the fast path pre-conditions, so unless a log
|
* We just updated the fast path pre-conditions, so unless a log
|
||||||
* truncation event happens again, we will hit the fast path.
|
* truncation event happens between the point where we dropped the lock
|
||||||
|
* and the point where we rearcuire it above, we will hit the fast
|
||||||
|
* path.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static off_t
|
static off_t
|
||||||
get_right(krb5_context context, krb5_storage *sp, int lastver, slave *s,
|
get_right(krb5_context context, int log_fd, krb5_storage *sp,
|
||||||
off_t left, uint32_t *verp)
|
int lastver, slave *s, off_t left, uint32_t *verp)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
uint32_t ver = s->version;
|
uint32_t ver = s->version;
|
||||||
off_t right = krb5_storage_seek(sp, left, SEEK_SET);
|
off_t right = krb5_storage_seek(sp, left, SEEK_SET);
|
||||||
|
|
||||||
if (right <= 0)
|
if (right <= 0) {
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* The "lastver" bound should preclude us reaching EOF */
|
/* The "lastver" bound should preclude us reaching EOF */
|
||||||
for (; ret == 0 && i < SEND_DIFFS_MAX_RECORDS && ver < lastver; ++i) {
|
for (; ret == 0 && i < SEND_DIFFS_MAX_RECORDS && ver < lastver; ++i) {
|
||||||
@@ -1164,23 +1101,18 @@ get_right(krb5_context context, krb5_storage *sp, int lastver, slave *s,
|
|||||||
right = krb5_storage_seek(sp, 0, SEEK_CUR);
|
right = krb5_storage_seek(sp, 0, SEEK_CUR);
|
||||||
else
|
else
|
||||||
right = -1;
|
right = -1;
|
||||||
if (right <= 0)
|
if (right <= 0) {
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
*verp = ver;
|
*verp = ver;
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void
|
||||||
* This function _must_ send something to the client unless it's dead, and if
|
send_diffs(kadm5_server_context *server_context, slave *s, int log_fd,
|
||||||
* dead it must mark it so (and so close the connection). It is an error to
|
|
||||||
* return from this function without having done so _unless_ the client is
|
|
||||||
* either dead or not ready.
|
|
||||||
*/
|
|
||||||
static kadm5_ret_t
|
|
||||||
send_diffs(kadm5_server_context *server_context, slave *s,
|
|
||||||
const char *database, uint32_t current_version)
|
const char *database, uint32_t current_version)
|
||||||
{
|
{
|
||||||
struct kadm5_log_snap snap;
|
|
||||||
krb5_context context = server_context->context;
|
krb5_context context = server_context->context;
|
||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
uint32_t initial_version;
|
uint32_t initial_version;
|
||||||
@@ -1190,122 +1122,84 @@ send_diffs(kadm5_server_context *server_context, slave *s,
|
|||||||
off_t right = 0;
|
off_t right = 0;
|
||||||
krb5_ssize_t bytes;
|
krb5_ssize_t bytes;
|
||||||
krb5_data data;
|
krb5_data data;
|
||||||
kadm5_ret_t ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/*
|
if (!diffready(context, s) || nodiffs(context, s, current_version))
|
||||||
* diffready() can send part of an extant buffer, and does nothing if the
|
return;
|
||||||
* client is either dead or not ready.
|
|
||||||
*/
|
|
||||||
if (!diffready(context, s))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* From this point onwards we cannot return without having sent anything */
|
|
||||||
|
|
||||||
if (nodiffs(context, s, current_version)) {
|
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "not sending diffs to up-to-date slave %s (no diffs)", s->name);
|
|
||||||
|
|
||||||
send_you_have_last_version(context, s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "sending diffs to live-seeming slave %s", s->name);
|
krb5_warnx(context, "sending diffs to live-seeming slave %s", s->name);
|
||||||
|
|
||||||
ret = kadm5_log_snapshot(server_context, &snap);
|
sp = krb5_storage_from_fd(log_fd);
|
||||||
if (ret) {
|
|
||||||
/*
|
|
||||||
* Here ret would be KADM5_LOG_CORRUPT. What can we do?
|
|
||||||
*/
|
|
||||||
send_you_have_last_version(context, s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp = krb5_storage_from_fd(server_context->log_context.log_fd);
|
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM,
|
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM,
|
||||||
"send_diffs: out of memory");
|
"send_diffs: out of memory");
|
||||||
|
|
||||||
left = get_left(server_context, s, sp, current_version,
|
left = get_left(server_context, s, sp, log_fd, current_version,
|
||||||
&initial_version, &initial_tstamp);
|
&initial_version, &initial_tstamp);
|
||||||
if (left < 0) {
|
if (left < 0) {
|
||||||
/* Some sort of error; fallback on full prop */
|
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (verbose)
|
slave_dead(context, s);
|
||||||
krb5_warnx(context, "sending full prop to slave %s "
|
return;
|
||||||
"(could not find offset for incremental)", s->name);
|
|
||||||
send_complete(context, s, database, current_version,
|
|
||||||
initial_version, initial_tstamp);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left == 0) {
|
if (left == 0) {
|
||||||
/* Slave's version is not in the log, fall back on send_complete() */
|
/* Slave's version is not in the log, fall back on send_complete() */
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (verbose)
|
|
||||||
krb5_warnx(context, "sending full prop to slave %s "
|
|
||||||
"(their version is too old)", s->name);
|
|
||||||
send_complete(context, s, database, current_version,
|
send_complete(context, s, database, current_version,
|
||||||
initial_version, initial_tstamp);
|
initial_version, initial_tstamp);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
right = get_right(server_context->context, sp, current_version,
|
/* We still hold the read lock, if right > 0 */
|
||||||
|
right = get_right(server_context->context, log_fd, sp, current_version,
|
||||||
s, left, &ver);
|
s, left, &ver);
|
||||||
if (right == left) {
|
if (right == left) {
|
||||||
/* Shouldn't happen */
|
flock(log_fd, LOCK_UN);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (verbose)
|
return;
|
||||||
krb5_warnx(context, "not sending diffs to up-to-date slave %s (weird)", s->name);
|
|
||||||
send_you_have_last_version(context, s);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (right < left) {
|
if (right < left) {
|
||||||
assert(right < 0);
|
assert(right < 0);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
slave_dead(context, s);
|
slave_dead(context, s);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (krb5_storage_seek(sp, left, SEEK_SET) != left) {
|
if (krb5_storage_seek(sp, left, SEEK_SET) != left) {
|
||||||
krb5_warn(context, errno ? errno : EIO, "send_diffs: krb5_storage_seek");
|
ret = errno ? errno : EIO;
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
|
krb5_warn(context, ret, "send_diffs: krb5_storage_seek");
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
slave_dead(context, s);
|
slave_dead(context, s);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_data_alloc(&data, right - left + 4);
|
ret = krb5_data_alloc(&data, right - left + 4);
|
||||||
if (ret)
|
if (ret) {
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
flock(log_fd, LOCK_UN);
|
||||||
|
krb5_warn(context, ret, "send_diffs: krb5_data_alloc");
|
||||||
|
krb5_storage_free(sp);
|
||||||
|
slave_dead(context, s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bytes = krb5_storage_read(sp, (char *)data.data + 4, data.length - 4);
|
bytes = krb5_storage_read(sp, (char *)data.data + 4, data.length - 4);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (bytes != data.length - 4) {
|
if (bytes != data.length - 4)
|
||||||
krb5_warnx(context, "send_diffs: log rotated");
|
krb5_errx(context, IPROPD_RESTART, "locked log truncated???");
|
||||||
return KADM5_LOG_SNAPSHOT_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = kadm5_log_snapshot_verify(server_context, &snap);
|
|
||||||
if (ret) {
|
|
||||||
krb5_data_free(&data);
|
|
||||||
if (ret == KADM5_LOG_SNAPSHOT_INVALID) {
|
|
||||||
krb5_warnx(context, "send_diffs: log rotated");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
sp = krb5_storage_from_data(&data);
|
sp = krb5_storage_from_data(&data);
|
||||||
if (sp == NULL)
|
if (sp == NULL) {
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
ret = krb5_store_uint32(sp, FOR_YOU);
|
ret = krb5_store_uint32(sp, FOR_YOU);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0)
|
||||||
ret = mk_priv_tail(context, s, &data);
|
ret = mk_priv_tail(context, s, &data);
|
||||||
if (ret == ENOMEM)
|
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ENOMEM, "out of memory");
|
|
||||||
}
|
|
||||||
krb5_data_free(&data);
|
krb5_data_free(&data);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* Save the fast-path continuation */
|
/* Save the fast-path continuation */
|
||||||
@@ -1327,10 +1221,10 @@ send_diffs(kadm5_server_context *server_context, slave *s,
|
|||||||
krb5_warn(context, ret, "send_diffs: making or sending "
|
krb5_warn(context, ret, "send_diffs: making or sending "
|
||||||
"KRB-PRIV message");
|
"KRB-PRIV message");
|
||||||
slave_dead(context, s);
|
slave_dead(context, s);
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
slave_seen(s);
|
slave_seen(s);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sensible bound on slave message size */
|
/* Sensible bound on slave message size */
|
||||||
@@ -1405,7 +1299,7 @@ read_msg(krb5_context context, slave *s, krb5_data *out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_msg(kadm5_server_context *server_context, slave *s,
|
process_msg(kadm5_server_context *server_context, slave *s, int log_fd,
|
||||||
const char *database, uint32_t current_version)
|
const char *database, uint32_t current_version)
|
||||||
{
|
{
|
||||||
krb5_context context = server_context->context;
|
krb5_context context = server_context->context;
|
||||||
@@ -1413,7 +1307,6 @@ process_msg(kadm5_server_context *server_context, slave *s,
|
|||||||
krb5_data out;
|
krb5_data out;
|
||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
int tries = 3;
|
|
||||||
|
|
||||||
ret = read_msg(context, s, &out);
|
ret = read_msg(context, s, &out);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -1479,9 +1372,9 @@ process_msg(kadm5_server_context *server_context, slave *s,
|
|||||||
krb5_warnx(context, "slave %s ready for updates from version %u",
|
krb5_warnx(context, "slave %s ready for updates from version %u",
|
||||||
s->name, tmp);
|
s->name, tmp);
|
||||||
}
|
}
|
||||||
do {
|
if ((s->version_ack = tmp) < s->version)
|
||||||
ret = send_diffs(server_context, s, database, current_version);
|
break;
|
||||||
} while (ret == KADM5_LOG_SNAPSHOT_INVALID && tries--);
|
send_diffs(server_context, s, log_fd, database, current_version);
|
||||||
break;
|
break;
|
||||||
case I_AM_HERE :
|
case I_AM_HERE :
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -1597,7 +1490,7 @@ write_stats(krb5_context context, slave *slaves, uint32_t current_version)
|
|||||||
} else
|
} else
|
||||||
rtbl_add_column_entry(tbl, SLAVE_ADDRESS, "<unknown>");
|
rtbl_add_column_entry(tbl, SLAVE_ADDRESS, "<unknown>");
|
||||||
|
|
||||||
snprintf(str, sizeof(str), "%u", (unsigned)slaves->version);
|
snprintf(str, sizeof(str), "%u", (unsigned)slaves->version_ack);
|
||||||
rtbl_add_column_entry(tbl, SLAVE_VERSION, str);
|
rtbl_add_column_entry(tbl, SLAVE_VERSION, str);
|
||||||
|
|
||||||
if (slaves->flags & SLAVE_F_DEAD)
|
if (slaves->flags & SLAVE_F_DEAD)
|
||||||
@@ -1677,14 +1570,14 @@ main(int argc, char **argv)
|
|||||||
void *kadm_handle;
|
void *kadm_handle;
|
||||||
kadm5_server_context *server_context;
|
kadm5_server_context *server_context;
|
||||||
kadm5_config_params conf;
|
kadm5_config_params conf;
|
||||||
krb5_socket_t signal_fd, listen_fds[2];
|
krb5_socket_t signal_fd, listen_fd;
|
||||||
|
int log_fd;
|
||||||
slave *slaves = NULL;
|
slave *slaves = NULL;
|
||||||
uint32_t current_version = 0, old_version = 0;
|
uint32_t current_version = 0, old_version = 0;
|
||||||
krb5_keytab keytab;
|
krb5_keytab keytab;
|
||||||
char **files;
|
char **files;
|
||||||
int aret;
|
int aret;
|
||||||
int optidx = 0;
|
int optidx = 0;
|
||||||
int num_listen_fds = 0;
|
|
||||||
int restarter_fd = -1;
|
int restarter_fd = -1;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
@@ -1782,19 +1675,24 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
server_context = (kadm5_server_context *)kadm_handle;
|
server_context = (kadm5_server_context *)kadm_handle;
|
||||||
|
|
||||||
ret = kadm5_log_init_nolock(server_context);
|
log_fd = open (server_context->log_context.log_file, O_RDONLY, 0);
|
||||||
if (ret)
|
if (log_fd < 0)
|
||||||
krb5_err(context, 1, ret, "Could not open iprop log file");
|
krb5_err (context, 1, errno, "open %s",
|
||||||
|
server_context->log_context.log_file);
|
||||||
|
|
||||||
if (fstat(server_context->log_context.log_fd, &st) == -1)
|
if (fstat(log_fd, &st) == -1)
|
||||||
krb5_err(context, 1, errno, "stat %s",
|
krb5_err(context, 1, errno, "stat %s",
|
||||||
server_context->log_context.log_file);
|
server_context->log_context.log_file);
|
||||||
|
|
||||||
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
if (flock(log_fd, LOCK_SH) == -1)
|
||||||
|
krb5_err(context, 1, errno, "shared flock %s",
|
||||||
|
server_context->log_context.log_file);
|
||||||
|
kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_LAST,
|
||||||
¤t_version, NULL);
|
¤t_version, NULL);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
|
|
||||||
signal_fd = make_signal_socket (context);
|
signal_fd = make_signal_socket (context);
|
||||||
make_listen_sockets(context, port_str, listen_fds, &num_listen_fds);
|
listen_fd = make_listen_socket (context, port_str);
|
||||||
|
|
||||||
krb5_warnx(context, "ipropd-master started at version: %lu",
|
krb5_warnx(context, "ipropd-master started at version: %lu",
|
||||||
(unsigned long)current_version);
|
(unsigned long)current_version);
|
||||||
@@ -1806,28 +1704,22 @@ main(int argc, char **argv)
|
|||||||
slave *p;
|
slave *p;
|
||||||
fd_set readset, writeset;
|
fd_set readset, writeset;
|
||||||
int max_fd = 0;
|
int max_fd = 0;
|
||||||
int nready;
|
|
||||||
int i;
|
|
||||||
struct timeval to = {30, 0};
|
struct timeval to = {30, 0};
|
||||||
uint32_t vers;
|
uint32_t vers;
|
||||||
struct stat st2;
|
struct stat st2;;
|
||||||
|
|
||||||
#ifndef NO_LIMIT_FD_SETSIZE
|
#ifndef NO_LIMIT_FD_SETSIZE
|
||||||
if (signal_fd >= FD_SETSIZE || restarter_fd >= FD_SETSIZE)
|
if (signal_fd >= FD_SETSIZE || listen_fd >= FD_SETSIZE ||
|
||||||
|
restarter_fd >= FD_SETSIZE)
|
||||||
krb5_errx (context, IPROPD_RESTART, "fd too large");
|
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");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FD_ZERO(&readset);
|
FD_ZERO(&readset);
|
||||||
FD_ZERO(&writeset);
|
FD_ZERO(&writeset);
|
||||||
FD_SET(signal_fd, &readset);
|
FD_SET(signal_fd, &readset);
|
||||||
max_fd = max(max_fd, signal_fd);
|
max_fd = max(max_fd, signal_fd);
|
||||||
for (i = 0; i < num_listen_fds; i++) {
|
FD_SET(listen_fd, &readset);
|
||||||
FD_SET(listen_fds[i], &readset);
|
max_fd = max(max_fd, listen_fd);
|
||||||
max_fd = max(max_fd, listen_fds[i]);
|
|
||||||
}
|
|
||||||
if (restarter_fd > -1) {
|
if (restarter_fd > -1) {
|
||||||
FD_SET(restarter_fd, &readset);
|
FD_SET(restarter_fd, &readset);
|
||||||
max_fd = max(max_fd, restarter_fd);
|
max_fd = max(max_fd, restarter_fd);
|
||||||
@@ -1849,7 +1741,6 @@ main(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
krb5_err (context, IPROPD_RESTART, errno, "select");
|
krb5_err (context, IPROPD_RESTART, errno, "select");
|
||||||
}
|
}
|
||||||
nready = ret;
|
|
||||||
|
|
||||||
if (stat(server_context->log_context.log_file, &st2) == -1) {
|
if (stat(server_context->log_context.log_file, &st2) == -1) {
|
||||||
krb5_warn(context, errno, "could not stat log file by path");
|
krb5_warn(context, errno, "could not stat log file by path");
|
||||||
@@ -1857,24 +1748,36 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (st2.st_dev != st.st_dev || st2.st_ino != st.st_ino) {
|
if (st2.st_dev != st.st_dev || st2.st_ino != st.st_ino) {
|
||||||
kadm5_log_end(server_context);
|
(void) close(log_fd);
|
||||||
|
|
||||||
ret = kadm5_log_init_nolock(server_context);
|
log_fd = open(server_context->log_context.log_file, O_RDONLY, 0);
|
||||||
if (ret)
|
if (log_fd < 0)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ret,
|
krb5_err(context, IPROPD_RESTART_SLOW, errno, "open %s",
|
||||||
"Could not re-open iprop log file");
|
server_context->log_context.log_file);
|
||||||
|
|
||||||
if (fstat(server_context->log_context.log_fd, &st) == -1)
|
if (fstat(log_fd, &st) == -1)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, errno, "stat %s",
|
krb5_err(context, IPROPD_RESTART_SLOW, errno, "stat %s",
|
||||||
server_context->log_context.log_file);
|
server_context->log_context.log_file);
|
||||||
|
|
||||||
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
if (flock(log_fd, LOCK_SH) == -1)
|
||||||
|
krb5_err(context, IPROPD_RESTART, errno, "shared flock %s",
|
||||||
|
server_context->log_context.log_file);
|
||||||
|
kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_LAST,
|
||||||
¤t_version, NULL);
|
¤t_version, NULL);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nready == 0) {
|
if (ret == 0) {
|
||||||
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
/* Recover from failed transactions */
|
||||||
|
if (kadm5_log_init_nb(server_context) == 0)
|
||||||
|
kadm5_log_end(server_context);
|
||||||
|
|
||||||
|
if (flock(log_fd, LOCK_SH) == -1)
|
||||||
|
krb5_err(context, IPROPD_RESTART, errno,
|
||||||
|
"could not lock log file");
|
||||||
|
kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_LAST,
|
||||||
¤t_version, NULL);
|
¤t_version, NULL);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
|
|
||||||
if (current_version > old_version) {
|
if (current_version > old_version) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -1883,25 +1786,21 @@ main(int argc, char **argv)
|
|||||||
(unsigned long)old_version,
|
(unsigned long)old_version,
|
||||||
(unsigned long)current_version);
|
(unsigned long)current_version);
|
||||||
for (p = slaves; p != NULL; p = p->next) {
|
for (p = slaves; p != NULL; p = p->next) {
|
||||||
int tries = 3;
|
|
||||||
|
|
||||||
if (p->flags & SLAVE_F_DEAD)
|
if (p->flags & SLAVE_F_DEAD)
|
||||||
continue;
|
continue;
|
||||||
do {
|
send_diffs(server_context, p, log_fd, database,
|
||||||
ret = send_diffs(server_context, p, database,
|
current_version);
|
||||||
current_version);
|
|
||||||
} while (ret == KADM5_LOG_SNAPSHOT_INVALID && tries--);
|
|
||||||
}
|
}
|
||||||
old_version = current_version;
|
old_version = current_version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nready && restarter_fd > -1 && FD_ISSET(restarter_fd, &readset)) {
|
if (ret && FD_ISSET(restarter_fd, &readset)) {
|
||||||
exit_flag = SIGTERM;
|
exit_flag = SIGTERM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nready && FD_ISSET(signal_fd, &readset)) {
|
if (ret && FD_ISSET(signal_fd, &readset)) {
|
||||||
#ifndef NO_UNIX_SOCKETS
|
#ifndef NO_UNIX_SOCKETS
|
||||||
struct sockaddr_un peer_addr;
|
struct sockaddr_un peer_addr;
|
||||||
#else
|
#else
|
||||||
@@ -1914,11 +1813,15 @@ main(int argc, char **argv)
|
|||||||
krb5_warn (context, errno, "recvfrom");
|
krb5_warn (context, errno, "recvfrom");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
--nready;
|
--ret;
|
||||||
assert(nready >= 0);
|
assert(ret >= 0);
|
||||||
old_version = current_version;
|
old_version = current_version;
|
||||||
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
if (flock(log_fd, LOCK_SH) == -1)
|
||||||
|
krb5_err(context, IPROPD_RESTART, errno, "shared flock %s",
|
||||||
|
server_context->log_context.log_file);
|
||||||
|
kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_LAST,
|
||||||
¤t_version, NULL);
|
¤t_version, NULL);
|
||||||
|
flock(log_fd, LOCK_UN);
|
||||||
if (current_version != old_version) {
|
if (current_version != old_version) {
|
||||||
/*
|
/*
|
||||||
* If current_version < old_version then the log got
|
* If current_version < old_version then the log got
|
||||||
@@ -1938,14 +1841,10 @@ main(int argc, char **argv)
|
|||||||
(unsigned long)old_version,
|
(unsigned long)old_version,
|
||||||
(unsigned long)current_version);
|
(unsigned long)current_version);
|
||||||
for (p = slaves; p != NULL; p = p->next) {
|
for (p = slaves; p != NULL; p = p->next) {
|
||||||
int tries = 3;
|
|
||||||
|
|
||||||
if (p->flags & SLAVE_F_DEAD)
|
if (p->flags & SLAVE_F_DEAD)
|
||||||
continue;
|
continue;
|
||||||
do {
|
send_diffs(server_context, p, log_fd, database,
|
||||||
ret = send_diffs(server_context, p, database,
|
current_version);
|
||||||
current_version);
|
|
||||||
} while (ret == EAGAIN && tries--);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -1960,39 +1859,31 @@ main(int argc, char **argv)
|
|||||||
FD_ISSET(p->fd, &writeset) &&
|
FD_ISSET(p->fd, &writeset) &&
|
||||||
((have_tail(p) && send_tail(context, p) == 0) ||
|
((have_tail(p) && send_tail(context, p) == 0) ||
|
||||||
(!have_tail(p) && more_diffs(p)))) {
|
(!have_tail(p) && more_diffs(p)))) {
|
||||||
int tries = 3;
|
send_diffs(server_context, p, log_fd, database,
|
||||||
|
current_version);
|
||||||
do {
|
|
||||||
ret = send_diffs(server_context, p, database,
|
|
||||||
current_version);
|
|
||||||
} while (ret == KADM5_LOG_SNAPSHOT_INVALID && tries--);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(p = slaves; p != NULL; p = p->next) {
|
for(p = slaves; p != NULL; p = p->next) {
|
||||||
if (p->flags & SLAVE_F_DEAD)
|
if (p->flags & SLAVE_F_DEAD)
|
||||||
continue;
|
continue;
|
||||||
if (nready && FD_ISSET(p->fd, &readset)) {
|
if (ret && FD_ISSET(p->fd, &readset)) {
|
||||||
--nready;
|
--ret;
|
||||||
assert(nready >= 0);
|
assert(ret >= 0);
|
||||||
ret = process_msg(server_context, p, database,
|
ret = process_msg(server_context, p, log_fd, database,
|
||||||
current_version);
|
current_version);
|
||||||
if (ret && ret != EWOULDBLOCK) {
|
if (ret && ret != EWOULDBLOCK)
|
||||||
krb5_warn(context, ret, "process_msg()");
|
|
||||||
slave_dead(context, p);
|
slave_dead(context, p);
|
||||||
}
|
|
||||||
} else if (slave_gone_p (p))
|
} else if (slave_gone_p (p))
|
||||||
slave_dead(context, p);
|
slave_dead(context, p);
|
||||||
else if (slave_missing_p (p))
|
else if (slave_missing_p (p))
|
||||||
send_are_you_there (context, p);
|
send_are_you_there (context, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; nready && i < num_listen_fds; i++) {
|
if (ret && FD_ISSET(listen_fd, &readset)) {
|
||||||
if (FD_ISSET(listen_fds[i], &readset)) {
|
add_slave (context, keytab, &slaves, listen_fd);
|
||||||
add_slave(context, keytab, &slaves, listen_fds[i]);
|
--ret;
|
||||||
--nready;
|
assert(ret >= 0);
|
||||||
assert(nready >= 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
write_stats(context, slaves, current_version);
|
write_stats(context, slaves, current_version);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,14 +124,16 @@ connect_to_master (krb5_context context, const char *master,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_creds(krb5_context context, krb5_ccache *cache)
|
get_creds(krb5_context context, krb5_ccache *cache, const char *serverhost)
|
||||||
{
|
{
|
||||||
krb5_keytab keytab;
|
krb5_keytab keytab;
|
||||||
krb5_principal client;
|
krb5_principal client;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_get_init_creds_opt *init_opts;
|
krb5_get_init_creds_opt *init_opts;
|
||||||
krb5_creds creds;
|
krb5_creds creds;
|
||||||
|
char *server;
|
||||||
char keytab_buf[256];
|
char keytab_buf[256];
|
||||||
|
int aret;
|
||||||
|
|
||||||
if (no_keytab_flag) {
|
if (no_keytab_flag) {
|
||||||
/* We're using an externally refreshed ccache */
|
/* We're using an externally refreshed ccache */
|
||||||
@@ -174,8 +176,13 @@ get_creds(krb5_context context, krb5_ccache *cache)
|
|||||||
ret = krb5_get_init_creds_opt_alloc(context, &init_opts);
|
ret = krb5_get_init_creds_opt_alloc(context, &init_opts);
|
||||||
if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
|
if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
|
||||||
|
|
||||||
|
aret = asprintf (&server, "%s/%s", IPROP_NAME, serverhost);
|
||||||
|
if (aret == -1 || server == NULL)
|
||||||
|
krb5_errx (context, 1, "malloc: no memory");
|
||||||
|
|
||||||
ret = krb5_get_init_creds_keytab(context, &creds, client, keytab,
|
ret = krb5_get_init_creds_keytab(context, &creds, client, keytab,
|
||||||
0, NULL, init_opts);
|
0, server, init_opts);
|
||||||
|
free (server);
|
||||||
krb5_get_init_creds_opt_free(context, init_opts);
|
krb5_get_init_creds_opt_free(context, init_opts);
|
||||||
if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");
|
if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");
|
||||||
|
|
||||||
@@ -348,6 +355,11 @@ receive_loop(krb5_context context,
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "receiving diffs");
|
krb5_warnx(context, "receiving diffs");
|
||||||
|
|
||||||
|
ret = kadm5_log_exclusivelock(server_context);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, IPROPD_RESTART, ret,
|
||||||
|
"Failed to lock iprop log for writes");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Seek to the first entry in the message from the master that is
|
* Seek to the first entry in the message from the master that is
|
||||||
* past the current version of the local database.
|
* past the current version of the local database.
|
||||||
@@ -465,6 +477,9 @@ receive(krb5_context context,
|
|||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ret, "db->close");
|
krb5_err(context, IPROPD_RESTART_SLOW, ret, "db->close");
|
||||||
|
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
kadm5_log_signal_master(server_context);
|
kadm5_log_signal_master(server_context);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "signaled master for hierarchical iprop");
|
krb5_warnx(context, "signaled master for hierarchical iprop");
|
||||||
@@ -516,6 +531,9 @@ reinit_log(krb5_context context,
|
|||||||
ret = kadm5_log_reinit(server_context, vno);
|
ret = kadm5_log_reinit(server_context, vno);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, IPROPD_RESTART_SLOW, ret, "kadm5_log_reinit");
|
krb5_err(context, IPROPD_RESTART_SLOW, ret, "kadm5_log_reinit");
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -535,6 +553,10 @@ receive_everything(krb5_context context, int fd,
|
|||||||
|
|
||||||
krb5_warnx(context, "receive complete database");
|
krb5_warnx(context, "receive complete database");
|
||||||
|
|
||||||
|
ret = kadm5_log_exclusivelock(server_context);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, IPROPD_RESTART, ret,
|
||||||
|
"Failed to lock iprop log for writes");
|
||||||
if (server_context->db->hdb_method_name) {
|
if (server_context->db->hdb_method_name) {
|
||||||
ret = asprintf(&dbname, "%.*s:%s-NEW",
|
ret = asprintf(&dbname, "%.*s:%s-NEW",
|
||||||
(int) strlen(server_context->db->hdb_method_name) - 1,
|
(int) strlen(server_context->db->hdb_method_name) - 1,
|
||||||
@@ -878,12 +900,15 @@ main(int argc, char **argv)
|
|||||||
ret = kadm5_log_init(server_context);
|
ret = kadm5_log_init(server_context);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, 1, ret, "kadm5_log_init");
|
krb5_err(context, 1, ret, "kadm5_log_init");
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
|
|
||||||
ret = server_context->db->hdb_close(context, server_context->db);
|
ret = server_context->db->hdb_close(context, server_context->db);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, 1, ret, "db->close");
|
krb5_err(context, 1, ret, "db->close");
|
||||||
|
|
||||||
get_creds(context, &ccache);
|
get_creds(context, &ccache, master);
|
||||||
|
|
||||||
ret = krb5_sname_to_principal (context, master, IPROP_NAME,
|
ret = krb5_sname_to_principal (context, master, IPROP_NAME,
|
||||||
KRB5_NT_SRV_HST, &server);
|
KRB5_NT_SRV_HST, &server);
|
||||||
@@ -949,7 +974,7 @@ main(int argc, char **argv)
|
|||||||
krb5_auth_con_free(context, auth_context);
|
krb5_auth_con_free(context, auth_context);
|
||||||
auth_context = NULL;
|
auth_context = NULL;
|
||||||
}
|
}
|
||||||
get_creds(context, &ccache);
|
get_creds(context, &ccache, master);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "authenticating to master");
|
krb5_warnx(context, "authenticating to master");
|
||||||
ret = krb5_sendauth (context, &auth_context, &master_fd,
|
ret = krb5_sendauth (context, &auth_context, &master_fd,
|
||||||
@@ -1066,6 +1091,9 @@ main(int argc, char **argv)
|
|||||||
krb5_err(context, IPROPD_RESTART, ret, "kadm5_log_init while "
|
krb5_err(context, IPROPD_RESTART, ret, "kadm5_log_init while "
|
||||||
"handling a message from the master");
|
"handling a message from the master");
|
||||||
}
|
}
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
|
|
||||||
ret = server_context->db->hdb_close (context, server_context->db);
|
ret = server_context->db->hdb_close (context, server_context->db);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -1097,6 +1125,7 @@ main(int argc, char **argv)
|
|||||||
krb5_warnx(context, "master sent us a full dump");
|
krb5_warnx(context, "master sent us a full dump");
|
||||||
ret = receive_everything(context, master_fd, server_context,
|
ret = receive_everything(context, master_fd, server_context,
|
||||||
auth_context);
|
auth_context);
|
||||||
|
(void) kadm5_log_sharedlock(server_context);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = ihave(context, auth_context, master_fd,
|
ret = ihave(context, auth_context, master_fd,
|
||||||
server_context->log_context.version);
|
server_context->log_context.version);
|
||||||
@@ -1105,6 +1134,8 @@ main(int argc, char **argv)
|
|||||||
connected = FALSE;
|
connected = FALSE;
|
||||||
else
|
else
|
||||||
is_up_to_date(context, status_file, server_context);
|
is_up_to_date(context, status_file, server_context);
|
||||||
|
if (verbose)
|
||||||
|
krb5_warnx(context, "downgraded iprop log lock to shared");
|
||||||
kadm5_log_signal_master(server_context);
|
kadm5_log_signal_master(server_context);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
krb5_warnx(context, "signaled master for hierarchical iprop");
|
krb5_warnx(context, "signaled master for hierarchical iprop");
|
||||||
@@ -1121,7 +1152,6 @@ main(int argc, char **argv)
|
|||||||
*
|
*
|
||||||
* So we don't ihave() here.
|
* So we don't ihave() here.
|
||||||
*/
|
*/
|
||||||
is_up_to_date(context, status_file, server_context);
|
|
||||||
send_im_here(context, master_fd, auth_context);
|
send_im_here(context, master_fd, auth_context);
|
||||||
break;
|
break;
|
||||||
case YOU_HAVE_LAST_VERSION:
|
case YOU_HAVE_LAST_VERSION:
|
||||||
@@ -1145,7 +1175,7 @@ main(int argc, char **argv)
|
|||||||
slave_status(context, status_file, "disconnected from master");
|
slave_status(context, status_file, "disconnected from master");
|
||||||
retry:
|
retry:
|
||||||
if (connected == FALSE)
|
if (connected == FALSE)
|
||||||
krb5_warnx (context, "disconnected from server");
|
krb5_warnx (context, "disconnected for server");
|
||||||
|
|
||||||
if (exit_flag)
|
if (exit_flag)
|
||||||
krb5_warnx (context, "got an exit signal");
|
krb5_warnx (context, "got an exit signal");
|
||||||
|
|||||||
@@ -73,8 +73,6 @@ error_code OLD_SERVER_HOOK_VERSION, "KADM5 server hook is too old for this versi
|
|||||||
error_code NEW_SERVER_HOOK_VERSION, "KADM5 server hook is too new for this version of Heimdal"
|
error_code NEW_SERVER_HOOK_VERSION, "KADM5 server hook is too new for this version of Heimdal"
|
||||||
error_code READ_ONLY, "Database is read-only; try primary server"
|
error_code READ_ONLY, "Database is read-only; try primary server"
|
||||||
error_code PASS_Q_GENERIC, "Unspecified password quality failure"
|
error_code PASS_Q_GENERIC, "Unspecified password quality failure"
|
||||||
error_code LOG_SNAPSHOT_INVALID, "Incremental propagation log rotated; restart operation"
|
|
||||||
error_code LOG_EMPTY, "Incremental propagation log is empty"
|
|
||||||
|
|
||||||
|
|
||||||
# MIT has:
|
# MIT has:
|
||||||
|
|||||||
@@ -86,7 +86,6 @@
|
|||||||
#include <hdb.h>
|
#include <hdb.h>
|
||||||
#include <der.h>
|
#include <der.h>
|
||||||
#include <parse_units.h>
|
#include <parse_units.h>
|
||||||
|
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
#endif /* __KADM5_LOCL_H__ */
|
#endif /* __KADM5_LOCL_H__ */
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ EXPORTS
|
|||||||
kadm5_log_init_sharedlock
|
kadm5_log_init_sharedlock
|
||||||
kadm5_log_next
|
kadm5_log_next
|
||||||
kadm5_log_nop
|
kadm5_log_nop
|
||||||
kadm5_log_snapshot
|
|
||||||
kadm5_log_snapshot_verify
|
|
||||||
kadm5_log_truncate
|
kadm5_log_truncate
|
||||||
kadm5_log_modify
|
kadm5_log_modify
|
||||||
_kadm5_acl_check_permission
|
_kadm5_acl_check_permission
|
||||||
|
|||||||
+15
-175
@@ -174,6 +174,12 @@ RCSID("$Id$");
|
|||||||
* will deadlock with ipropd-slave -- don't do that.
|
* will deadlock with ipropd-slave -- don't do that.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define LOG_HEADER_SZ ((off_t)(sizeof(uint32_t) * 4))
|
||||||
|
#define LOG_TRAILER_SZ ((off_t)(sizeof(uint32_t) * 2))
|
||||||
|
#define LOG_WRAPPER_SZ ((off_t)(LOG_HEADER_SZ + LOG_TRAILER_SZ))
|
||||||
|
#define LOG_UBER_LEN ((off_t)(sizeof(uint64_t) + sizeof(uint32_t) * 2))
|
||||||
|
#define LOG_UBER_SZ ((off_t)(LOG_WRAPPER_SZ + LOG_UBER_LEN))
|
||||||
|
|
||||||
#define LOG_NOPEEK 0
|
#define LOG_NOPEEK 0
|
||||||
#define LOG_DOPEEK 1
|
#define LOG_DOPEEK 1
|
||||||
|
|
||||||
@@ -484,46 +490,12 @@ kadm5_log_get_version_fd(kadm5_server_context *server_context, int fd,
|
|||||||
{
|
{
|
||||||
kadm5_ret_t ret = 0;
|
kadm5_ret_t ret = 0;
|
||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
if (tstamp == NULL)
|
|
||||||
tstamp = &tmp;
|
|
||||||
|
|
||||||
*ver = 0;
|
|
||||||
*tstamp = 0;
|
|
||||||
|
|
||||||
if (fd == -1)
|
|
||||||
fd = server_context->log_context.log_fd;
|
|
||||||
|
|
||||||
sp = krb5_storage_from_fd(fd);
|
|
||||||
if (sp == NULL)
|
|
||||||
return errno ? errno : ENOMEM;
|
|
||||||
|
|
||||||
ret = kadm5_log_get_version_sp(server_context, sp, which, ver, tstamp);
|
|
||||||
krb5_storage_free(sp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_log_get_version_sp(kadm5_server_context *server_context, krb5_storage *sp,
|
|
||||||
int which, uint32_t *ver, uint32_t *tstamp)
|
|
||||||
{
|
|
||||||
struct kadm5_log_snap snap;
|
|
||||||
kadm5_ret_t ret = 0;
|
|
||||||
enum kadm_ops op = kadm_get;
|
enum kadm_ops op = kadm_get;
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
/*
|
if (fd == -1)
|
||||||
* If we're operating lock-less-ly then get a snapshot of the log so we can
|
return 0; /* /dev/null */
|
||||||
* validate that what we read here is correct once we're done reading it.
|
|
||||||
*/
|
|
||||||
memset(&snap, 0, sizeof(snap));
|
|
||||||
if (server_context->log_context.lock_mode == LOCK_UN) {
|
|
||||||
ret = kadm5_log_snapshot(server_context, &snap);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tstamp == NULL)
|
if (tstamp == NULL)
|
||||||
tstamp = &tmp;
|
tstamp = &tmp;
|
||||||
@@ -531,6 +503,10 @@ kadm5_log_get_version_sp(kadm5_server_context *server_context, krb5_storage *sp,
|
|||||||
*ver = 0;
|
*ver = 0;
|
||||||
*tstamp = 0;
|
*tstamp = 0;
|
||||||
|
|
||||||
|
sp = krb5_storage_from_fd(fd);
|
||||||
|
if (sp == NULL)
|
||||||
|
return errno ? errno : ENOMEM;
|
||||||
|
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case LOG_VERSION_LAST:
|
case LOG_VERSION_LAST:
|
||||||
ret = kadm5_log_goto_end(server_context, sp);
|
ret = kadm5_log_goto_end(server_context, sp);
|
||||||
@@ -555,92 +531,10 @@ kadm5_log_get_version_sp(kadm5_server_context *server_context, krb5_storage *sp,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0 && server_context->log_context.lock_mode == LOCK_UN)
|
krb5_storage_free(sp);
|
||||||
/* Validate the snapshot when operating lock-less-ly */
|
|
||||||
return kadm5_log_snapshot_verify(server_context, &snap);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* For lock-less reading of the log first get a snapshot, then read, then
|
|
||||||
* verify the snapshot before using the data read. If snapshot verification
|
|
||||||
* fails, start over.
|
|
||||||
*
|
|
||||||
* This will be used in ipropd-master and iprop-log to avoid needing a lock on
|
|
||||||
* the iprop log. For example, when a client says I_HAVE $ver then the server
|
|
||||||
* gets a snapshot, finds the offset to $ver and the offset to the end of the
|
|
||||||
* log, reads all that into memory, then the server veerifies the snapshot, and
|
|
||||||
* finally it sends the data to client, but if the snapshot verification fails
|
|
||||||
* then the server starts over the process of finding the offset to $ver.
|
|
||||||
*
|
|
||||||
* The way this works is that as long as the log is not rotated and truncated,
|
|
||||||
* then we can expect the header of the first record after the uber-record to
|
|
||||||
* remain the same.
|
|
||||||
*/
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_log_snapshot(kadm5_server_context *server_context,
|
|
||||||
struct kadm5_log_snap *snap)
|
|
||||||
{
|
|
||||||
ssize_t bytes;
|
|
||||||
|
|
||||||
assert(sizeof(snap->buf) < CHAR_MAX);
|
|
||||||
snap->bytes = 0;
|
|
||||||
|
|
||||||
bytes = pread(server_context->log_context.log_fd,
|
|
||||||
snap->buf, sizeof(snap->buf), 0);
|
|
||||||
if (bytes < 0)
|
|
||||||
return errno;
|
|
||||||
if (bytes < LOG_UBER_SZ)
|
|
||||||
return KADM5_LOG_CORRUPT;
|
|
||||||
if (bytes < sizeof(snap->buf))
|
|
||||||
bytes = LOG_UBER_SZ;
|
|
||||||
|
|
||||||
snap->bytes = bytes;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* kadm5_log_snapshot_verify() checks that the iprop log has not been rotated
|
|
||||||
* since the given `snap` snapshot. Returns -1 if the log has been rotated.
|
|
||||||
*/
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_log_snapshot_verify(kadm5_server_context *server_context,
|
|
||||||
struct kadm5_log_snap *snap)
|
|
||||||
{
|
|
||||||
struct kadm5_log_snap v;
|
|
||||||
kadm5_ret_t ret;
|
|
||||||
|
|
||||||
assert(sizeof(snap->buf) < CHAR_MAX);
|
|
||||||
if (snap->bytes < LOG_UBER_SZ)
|
|
||||||
return KADM5_LOG_SNAPSHOT_INVALID;
|
|
||||||
|
|
||||||
ret = kadm5_log_snapshot(server_context, &v);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (v.bytes < LOG_UBER_SZ)
|
|
||||||
return KADM5_LOG_CORRUPT;
|
|
||||||
|
|
||||||
/* The two snapshots are equal -> no log rotation, no log change at all */
|
|
||||||
if (snap->bytes == v.bytes && memcmp(snap->buf, v.buf, v.bytes) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Both snapshots capture the first record's header past the uber record?
|
|
||||||
* Check that that first record's header is the same for both.
|
|
||||||
*/
|
|
||||||
if (snap->bytes == v.bytes && v.bytes == sizeof(v.buf) &&
|
|
||||||
memcmp(snap->buf + LOG_UBER_SZ, v.buf + LOG_UBER_SZ,
|
|
||||||
LOG_HEADER_SZ) == 0)
|
|
||||||
return 0; /* No log rotation, but the log did change */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Log rotated, or we don't have any log entries but the uber record
|
|
||||||
* changed.
|
|
||||||
*/
|
|
||||||
return KADM5_LOG_SNAPSHOT_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the version of the last confirmed entry in the log */
|
/* Get the version of the last confirmed entry in the log */
|
||||||
kadm5_ret_t
|
kadm5_ret_t
|
||||||
kadm5_log_get_version(kadm5_server_context *server_context, uint32_t *ver)
|
kadm5_log_get_version(kadm5_server_context *server_context, uint32_t *ver)
|
||||||
@@ -2239,7 +2133,7 @@ kadm5_log_goto_first(kadm5_server_context *server_context, krb5_storage *sp)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (op == kadm_nop && len == LOG_UBER_LEN && seek_next(sp) == -1)
|
if (op == kadm_nop && len == LOG_UBER_LEN && seek_next(sp) == -1)
|
||||||
return KADM5_LOG_EMPTY;
|
return KADM5_LOG_CORRUPT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2609,13 +2503,6 @@ load_entries(kadm5_server_context *context, krb5_data *p,
|
|||||||
/*
|
/*
|
||||||
* Truncate the log, retaining at most `keep' entries and at most `maxbytes'.
|
* Truncate the log, retaining at most `keep' entries and at most `maxbytes'.
|
||||||
* If `maxbytes' is zero, keep at most the default log size limit.
|
* If `maxbytes' is zero, keep at most the default log size limit.
|
||||||
*
|
|
||||||
* I.e., rotate the log, except we don't rename a new log into place.
|
|
||||||
*
|
|
||||||
* Ensures that the log will be smaller than prior to truncation. This is
|
|
||||||
* important as it ensures that the log snapshot approach used by ipropd-master
|
|
||||||
* to read the log lock-less-ly will work. See also kadm5_log_snapshot() and
|
|
||||||
* kadm5_log_snapshot_verify().
|
|
||||||
*/
|
*/
|
||||||
kadm5_ret_t
|
kadm5_ret_t
|
||||||
kadm5_log_truncate(kadm5_server_context *context, size_t keep, size_t maxbytes)
|
kadm5_log_truncate(kadm5_server_context *context, size_t keep, size_t maxbytes)
|
||||||
@@ -2627,10 +2514,7 @@ kadm5_log_truncate(kadm5_server_context *context, size_t keep, size_t maxbytes)
|
|||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
uint64_t sz;
|
uint64_t sz;
|
||||||
off_t off, fsz;
|
off_t off;
|
||||||
|
|
||||||
if ((fsz = lseek(context->log_context.log_fd, 0, SEEK_END)) < 0)
|
|
||||||
return errno;
|
|
||||||
|
|
||||||
if (maxbytes == 0)
|
if (maxbytes == 0)
|
||||||
maxbytes = get_max_log_size(context->context);
|
maxbytes = get_max_log_size(context->context);
|
||||||
@@ -2665,50 +2549,6 @@ kadm5_log_truncate(kadm5_server_context *context, size_t keep, size_t maxbytes)
|
|||||||
return EOVERFLOW; /* caller should ask for fewer entries */
|
return EOVERFLOW; /* caller should ask for fewer entries */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure that the iprop log will be smaller, or defer truncation */
|
|
||||||
if (sz >= fsz) {
|
|
||||||
uint32_t skip;
|
|
||||||
|
|
||||||
krb5_data_free(&entries);
|
|
||||||
|
|
||||||
if (first > last)
|
|
||||||
first = 1;
|
|
||||||
|
|
||||||
skip = (last - first) / 2;
|
|
||||||
|
|
||||||
if (skip < 2) {
|
|
||||||
/*
|
|
||||||
* There must be an entry that is just large enough, or larger,
|
|
||||||
* that it alone causes the log to exceed the log size
|
|
||||||
* limit.
|
|
||||||
*/
|
|
||||||
krb5_warnx(context->context,
|
|
||||||
"Unable to truncate log due to very large record; "
|
|
||||||
"deferring truncation");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
first += (last - first) / 2;
|
|
||||||
ret = load_entries(context, &entries, last - first, maxbytes, &first, &last);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
sz = LOG_UBER_SZ + entries.length;
|
|
||||||
off = (off_t)sz;
|
|
||||||
if (off < 0 || off != sz || sz < entries.length) {
|
|
||||||
krb5_data_free(&entries);
|
|
||||||
return EOVERFLOW; /* caller should ask for fewer entries */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sz >= fsz) {
|
|
||||||
/* Should never happen! */
|
|
||||||
krb5_data_free(&entries);
|
|
||||||
krb5_warnx(context->context,
|
|
||||||
"Unable to truncate log due to very large record; "
|
|
||||||
"deferring truncation");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Truncate to zero size and seek to zero offset */
|
/* Truncate to zero size and seek to zero offset */
|
||||||
if (ftruncate(context->log_context.log_fd, 0) < 0 ||
|
if (ftruncate(context->log_context.log_fd, 0) < 0 ||
|
||||||
lseek(context->log_context.log_fd, 0, SEEK_SET) < 0) {
|
lseek(context->log_context.log_fd, 0, SEEK_SET) < 0) {
|
||||||
|
|||||||
@@ -87,8 +87,6 @@ HEIMDAL_KAMD5_SERVER_1.0 {
|
|||||||
kadm5_log_init_sharedlock;
|
kadm5_log_init_sharedlock;
|
||||||
kadm5_log_next;
|
kadm5_log_next;
|
||||||
kadm5_log_nop;
|
kadm5_log_nop;
|
||||||
kadm5_log_snapshot;
|
|
||||||
kadm5_log_snapshot_verify;
|
|
||||||
kadm5_log_truncate;
|
kadm5_log_truncate;
|
||||||
kadm5_log_modify;
|
kadm5_log_modify;
|
||||||
_kadm5_acl_check_permission;
|
_kadm5_acl_check_permission;
|
||||||
|
|||||||
+30
-33
@@ -704,30 +704,25 @@ change_password_loop (krb5_context context,
|
|||||||
* do the SOCKS4a I/O.
|
* do the SOCKS4a I/O.
|
||||||
*/
|
*/
|
||||||
while (!_krb5_socks4a_connected(socks4a)) {
|
while (!_krb5_socks4a_connected(socks4a)) {
|
||||||
struct pollfd pfd;
|
fd_set readfds, writefds;
|
||||||
int nready;
|
int nready;
|
||||||
|
|
||||||
pfd.fd = sock;
|
FD_ZERO(&readfds);
|
||||||
pfd.events = 0;
|
FD_ZERO(&writefds);
|
||||||
pfd.revents = 0;
|
|
||||||
|
|
||||||
if (_krb5_socks4a_reading(socks4a))
|
if (_krb5_socks4a_reading(socks4a))
|
||||||
pfd.events |= POLLIN;
|
FD_SET(sock, &readfds);
|
||||||
if (_krb5_socks4a_writing(socks4a))
|
if (_krb5_socks4a_writing(socks4a))
|
||||||
pfd.events |= POLLOUT;
|
FD_SET(sock, &writefds);
|
||||||
|
nready = select(sock + 1, &readfds, &writefds,
|
||||||
nready = poll(&pfd, 1, -1); /* blocking */
|
/*exceptfds*/NULL, /*timeout*/NULL);
|
||||||
if (nready < 0) {
|
if (nready == -1) {
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
ret = errno;
|
ret = errno;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nready == 0) {
|
if (nready <= 0) {
|
||||||
ret = EIO; /* timeout should be impossible */
|
ret = EIO; /* timeout should be impossible */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = _krb5_socks4a_io(socks4a);
|
ret = _krb5_socks4a_io(socks4a);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
@@ -738,6 +733,9 @@ change_password_loop (krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; !done && i < 5; ++i) {
|
for (i = 0; !done && i < 5; ++i) {
|
||||||
|
fd_set fdset;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
if (!replied) {
|
if (!replied) {
|
||||||
replied = 0;
|
replied = 0;
|
||||||
|
|
||||||
@@ -755,28 +753,27 @@ change_password_loop (krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pollfd pfd;
|
#ifndef NO_LIMIT_FD_SETSIZE
|
||||||
int timeout_ms;
|
if (sock >= FD_SETSIZE) {
|
||||||
timeout_ms = (1 + (1 << i)) * 1000;
|
ret = ERANGE;
|
||||||
|
krb5_set_error_message(context, ret,
|
||||||
pfd.fd = sock;
|
"fd %d too large", sock);
|
||||||
pfd.events = POLLIN;
|
rk_closesocket (sock);
|
||||||
pfd.revents = 0;
|
goto out;
|
||||||
|
|
||||||
ret = poll(&pfd, 1, timeout_ms);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
rk_closesocket(sock);
|
|
||||||
ret = errno;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == 0) {
|
FD_ZERO(&fdset);
|
||||||
ret = KRB5_KDC_UNREACH;
|
FD_SET(sock, &fdset);
|
||||||
continue;
|
tv.tv_usec = 0;
|
||||||
|
tv.tv_sec = 1 + (1 << i);
|
||||||
|
|
||||||
|
ret = select (sock + 1, &fdset, NULL, NULL, &tv);
|
||||||
|
if (rk_IS_SOCKET_ERROR(ret) && rk_SOCK_ERRNO != EINTR) {
|
||||||
|
rk_closesocket(sock);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
if (pfd.revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL)) {
|
if (ret == 1) {
|
||||||
ret = (*proc->process_rep) (context,
|
ret = (*proc->process_rep) (context,
|
||||||
auth_context,
|
auth_context,
|
||||||
is_stream,
|
is_stream,
|
||||||
|
|||||||
+4
-4
@@ -489,7 +489,7 @@ init_context_from_config_file(krb5_context context)
|
|||||||
|
|
||||||
tmp = secure_getenv("KRB5_TRACE");
|
tmp = secure_getenv("KRB5_TRACE");
|
||||||
if (tmp)
|
if (tmp)
|
||||||
heim_add_trace_dest(context->hcontext, "libkrb5", tmp);
|
heim_add_debug_dest(context->hcontext, "libkrb5", tmp);
|
||||||
s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL);
|
s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL);
|
||||||
if (s) {
|
if (s) {
|
||||||
char **p;
|
char **p;
|
||||||
@@ -1108,15 +1108,15 @@ krb5_kerberos_enctypes(krb5_context context)
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const krb5_enctype weak[] = {
|
static const krb5_enctype weak[] = {
|
||||||
ETYPE_AES256_CTS_HMAC_SHA384_192,
|
|
||||||
ETYPE_AES128_CTS_HMAC_SHA256_128,
|
|
||||||
ETYPE_AES256_CTS_HMAC_SHA1_96,
|
ETYPE_AES256_CTS_HMAC_SHA1_96,
|
||||||
ETYPE_AES128_CTS_HMAC_SHA1_96,
|
ETYPE_AES128_CTS_HMAC_SHA1_96,
|
||||||
|
ETYPE_AES256_CTS_HMAC_SHA384_192,
|
||||||
|
ETYPE_AES128_CTS_HMAC_SHA256_128,
|
||||||
ETYPE_ARCFOUR_HMAC_MD5,
|
ETYPE_ARCFOUR_HMAC_MD5,
|
||||||
ETYPE_NULL
|
ETYPE_NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
if (krb5_enctype_valid(context, ETYPE_ARCFOUR_HMAC_MD5) == 0)
|
if (krb5_enctype_valid(context, ETYPE_ARCFOUR_HMAC_MD5))
|
||||||
return weak;
|
return weak;
|
||||||
|
|
||||||
return strong;
|
return strong;
|
||||||
|
|||||||
@@ -608,12 +608,8 @@ krb5_create_checksum(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arcfour_checksum_p(ct, crypto)) {
|
if (arcfour_checksum_p(ct, crypto)) {
|
||||||
#ifdef HEIM_ARCFOUR
|
|
||||||
keyusage = usage;
|
keyusage = usage;
|
||||||
_krb5_usage2arcfour(context, &keyusage);
|
_krb5_usage2arcfour(context, &keyusage);
|
||||||
#else
|
|
||||||
return KRB5_PROG_SUMTYPE_NOSUPP;
|
|
||||||
#endif /* HEIM_ARCFOUR */
|
|
||||||
} else
|
} else
|
||||||
keyusage = CHECKSUM_USAGE(usage);
|
keyusage = CHECKSUM_USAGE(usage);
|
||||||
|
|
||||||
@@ -742,12 +738,8 @@ krb5_verify_checksum(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arcfour_checksum_p(ct, crypto)) {
|
if (arcfour_checksum_p(ct, crypto)) {
|
||||||
#ifdef HEIM_ARCFOUR
|
|
||||||
keyusage = usage;
|
keyusage = usage;
|
||||||
_krb5_usage2arcfour(context, &keyusage);
|
_krb5_usage2arcfour(context, &keyusage);
|
||||||
#else
|
|
||||||
return KRB5_PROG_SUMTYPE_NOSUPP;
|
|
||||||
#endif /* HEIM_ARCFOUR */
|
|
||||||
} else
|
} else
|
||||||
keyusage = CHECKSUM_USAGE(usage);
|
keyusage = CHECKSUM_USAGE(usage);
|
||||||
|
|
||||||
@@ -2075,12 +2067,8 @@ krb5_create_checksum_iov(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arcfour_checksum_p(ct, crypto)) {
|
if (arcfour_checksum_p(ct, crypto)) {
|
||||||
#ifdef HEIM_ARCFOUR
|
|
||||||
keyusage = usage;
|
keyusage = usage;
|
||||||
_krb5_usage2arcfour(context, &keyusage);
|
_krb5_usage2arcfour(context, &keyusage);
|
||||||
#else
|
|
||||||
return KRB5_PROG_SUMTYPE_NOSUPP;
|
|
||||||
#endif /* HEIM_ARCFOUR */
|
|
||||||
} else
|
} else
|
||||||
keyusage = CHECKSUM_USAGE(usage);
|
keyusage = CHECKSUM_USAGE(usage);
|
||||||
|
|
||||||
@@ -2146,12 +2134,8 @@ krb5_verify_checksum_iov(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arcfour_checksum_p(ct, crypto)) {
|
if (arcfour_checksum_p(ct, crypto)) {
|
||||||
#ifdef HEIM_ARCFOUR
|
|
||||||
keyusage = usage;
|
keyusage = usage;
|
||||||
_krb5_usage2arcfour(context, &keyusage);
|
_krb5_usage2arcfour(context, &keyusage);
|
||||||
#else
|
|
||||||
return KRB5_PROG_SUMTYPE_NOSUPP;
|
|
||||||
#endif /* HEIM_ARCFOUR */
|
|
||||||
} else
|
} else
|
||||||
keyusage = CHECKSUM_USAGE(usage);
|
keyusage = CHECKSUM_USAGE(usage);
|
||||||
|
|
||||||
|
|||||||
@@ -69,17 +69,22 @@ krb5_expand_hostname (krb5_context context,
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0 ||
|
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0 ||
|
||||||
krb5_config_get_bool(context, NULL, "libdefaults", "block_dns", NULL))
|
krb5_config_get_bool(context, NULL, "libdefaults", "block_dns", NULL)) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname: DNS canonicalization disabled or blocked for hostname %s", orig_hostname);
|
||||||
return copy_hostname (context, orig_hostname, new_hostname);
|
return copy_hostname (context, orig_hostname, new_hostname);
|
||||||
|
}
|
||||||
|
|
||||||
memset (&hints, 0, sizeof(hints));
|
memset (&hints, 0, sizeof(hints));
|
||||||
hints.ai_flags = AI_CANONNAME;
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
|
||||||
error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
|
error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
|
||||||
if (error)
|
if (error) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname: getaddrinfo(%s) failed: %s", orig_hostname, gai_strerror(error));
|
||||||
return copy_hostname (context, orig_hostname, new_hostname);
|
return copy_hostname (context, orig_hostname, new_hostname);
|
||||||
|
}
|
||||||
for (a = ai; a != NULL; a = a->ai_next) {
|
for (a = ai; a != NULL; a = a->ai_next) {
|
||||||
if (a->ai_canonname != NULL) {
|
if (a->ai_canonname != NULL) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname: canonical name for %s -> %s", orig_hostname, a->ai_canonname);
|
||||||
*new_hostname = strdup (a->ai_canonname);
|
*new_hostname = strdup (a->ai_canonname);
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
if (*new_hostname == NULL)
|
if (*new_hostname == NULL)
|
||||||
@@ -89,6 +94,7 @@ krb5_expand_hostname (krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname: no canonical name found for %s, falling back to copy_hostname", orig_hostname);
|
||||||
return copy_hostname (context, orig_hostname, new_hostname);
|
return copy_hostname (context, orig_hostname, new_hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,20 +151,25 @@ krb5_expand_hostname_realms (krb5_context context,
|
|||||||
int error;
|
int error;
|
||||||
krb5_error_code ret = 0;
|
krb5_error_code ret = 0;
|
||||||
|
|
||||||
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
|
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: DNS canonicalization disabled for hostname %s", orig_hostname);
|
||||||
return vanilla_hostname (context, orig_hostname, new_hostname,
|
return vanilla_hostname (context, orig_hostname, new_hostname,
|
||||||
realms);
|
realms);
|
||||||
|
}
|
||||||
|
|
||||||
memset (&hints, 0, sizeof(hints));
|
memset (&hints, 0, sizeof(hints));
|
||||||
hints.ai_flags = AI_CANONNAME;
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
|
||||||
error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
|
error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
|
||||||
if (error)
|
if (error) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: getaddrinfo(%s) failed: %s", orig_hostname, gai_strerror(error));
|
||||||
return vanilla_hostname (context, orig_hostname, new_hostname,
|
return vanilla_hostname (context, orig_hostname, new_hostname,
|
||||||
realms);
|
realms);
|
||||||
|
}
|
||||||
|
|
||||||
for (a = ai; a != NULL; a = a->ai_next) {
|
for (a = ai; a != NULL; a = a->ai_next) {
|
||||||
if (a->ai_canonname != NULL) {
|
if (a->ai_canonname != NULL) {
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: canonical name for %s -> %s", orig_hostname, a->ai_canonname);
|
||||||
ret = copy_hostname (context, a->ai_canonname, new_hostname);
|
ret = copy_hostname (context, a->ai_canonname, new_hostname);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
@@ -168,11 +179,13 @@ krb5_expand_hostname_realms (krb5_context context,
|
|||||||
ret = krb5_get_host_realm (context, *new_hostname, realms);
|
ret = krb5_get_host_realm (context, *new_hostname, realms);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: host %s mapped to realm %s", *new_hostname, realms && *realms ? (*realms)[0] : "<unknown>");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free (*new_hostname);
|
free (*new_hostname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
|
krb5_warnx(context, "krb5_expand_hostname_realms: no canonical name/realm found for %s, falling back to vanilla_hostname", orig_hostname);
|
||||||
return vanilla_hostname (context, orig_hostname, new_hostname, realms);
|
return vanilla_hostname (context, orig_hostname, new_hostname, realms);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1081,6 +1081,7 @@ cred_delete(krb5_context context,
|
|||||||
ret = krb5_storage_to_data(sp, &orig_cred_data);
|
ret = krb5_storage_to_data(sp, &orig_cred_data);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
krb5_storage_free(sp);
|
||||||
|
|
||||||
cred_data_in_file = malloc(orig_cred_data.length);
|
cred_data_in_file = malloc(orig_cred_data.length);
|
||||||
if (cred_data_in_file == NULL)
|
if (cred_data_in_file == NULL)
|
||||||
@@ -1102,7 +1103,6 @@ cred_delete(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
krb5_storage_free(sp);
|
|
||||||
sp = krb5_storage_emem();
|
sp = krb5_storage_emem();
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
+1
-1
@@ -645,7 +645,7 @@ get_cred_kdc(krb5_context context,
|
|||||||
krb5_sendto_ctx stctx;
|
krb5_sendto_ctx stctx;
|
||||||
ret = krb5_sendto_ctx_alloc(context, &stctx);
|
ret = krb5_sendto_ctx_alloc(context, &stctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
return ret;
|
||||||
krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL);
|
krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL);
|
||||||
|
|
||||||
if (kdc_hostname)
|
if (kdc_hostname)
|
||||||
|
|||||||
+114
-2
@@ -217,6 +217,31 @@ krb5_kt_resolve(krb5_context context,
|
|||||||
|
|
||||||
residual = keytab_name(name, &type, &type_len);
|
residual = keytab_name(name, &type, &type_len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Aggressive process-context logging:
|
||||||
|
* Print pid/ppid/uid/gid and the raw name string being resolved
|
||||||
|
* so test captures show which process attempted to resolve which
|
||||||
|
* keytab and with what parsed type/residual.
|
||||||
|
*
|
||||||
|
* We intentionally always emit this via krb5_warnx to make sure it
|
||||||
|
* appears in stderr/journal during tests.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
pid_t pid = getpid();
|
||||||
|
pid_t ppid = getppid();
|
||||||
|
uid_t uid = getuid();
|
||||||
|
gid_t gid = getgid();
|
||||||
|
krb5_warnx(context,
|
||||||
|
"krb5_kt_resolve: pid=%d ppid=%d uid=%d gid=%d resolving name=\"%s\" parsed_type=\"%.*s\" residual=\"%s\"",
|
||||||
|
(int)pid,
|
||||||
|
(int)ppid,
|
||||||
|
(int)uid,
|
||||||
|
(int)gid,
|
||||||
|
name ? name : "<null>",
|
||||||
|
(int)type_len, type ? type : "<null>",
|
||||||
|
residual ? residual : "<null>");
|
||||||
|
}
|
||||||
|
|
||||||
for(i = 0; i < context->num_kt_types; i++) {
|
for(i = 0; i < context->num_kt_types; i++) {
|
||||||
if(strncasecmp(type, context->kt_types[i].prefix, type_len) == 0)
|
if(strncasecmp(type, context->kt_types[i].prefix, type_len) == 0)
|
||||||
break;
|
break;
|
||||||
@@ -251,8 +276,15 @@ static const char *default_ktname(krb5_context context)
|
|||||||
const char *tmp = NULL;
|
const char *tmp = NULL;
|
||||||
|
|
||||||
tmp = secure_getenv("KRB5_KTNAME");
|
tmp = secure_getenv("KRB5_KTNAME");
|
||||||
if(tmp != NULL)
|
if(tmp != NULL) {
|
||||||
|
/* Aggressive logging: record environment override */
|
||||||
|
krb5_warnx(context, "default_ktname: using KRB5_KTNAME from env: \"%s\" (pid=%d)", tmp, (int)getpid());
|
||||||
return tmp;
|
return tmp;
|
||||||
|
}
|
||||||
|
/* Aggressive logging: record context default choice as well */
|
||||||
|
krb5_warnx(context, "default_ktname: using context->default_keytab: \"%s\" (pid=%d)",
|
||||||
|
context->default_keytab ? context->default_keytab : "<null>",
|
||||||
|
(int)getpid());
|
||||||
return context->default_keytab;
|
return context->default_keytab;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,6 +629,13 @@ _krb5_kt_principal_not_found(krb5_context context,
|
|||||||
else
|
else
|
||||||
kvno_str[0] = '\0';
|
kvno_str[0] = '\0';
|
||||||
|
|
||||||
|
/* Provide a concise debug line so tests can see what principal/keytab/enctype failed */
|
||||||
|
krb5_warnx(context, "kt_principal_not_found: principal=%s kvno=%s keytab=%s enctype=%s",
|
||||||
|
princ ? princ : "<unknown>",
|
||||||
|
kvno_str[0] ? kvno_str : "<none>",
|
||||||
|
kt_name ? kt_name : "unknown keytab",
|
||||||
|
enctype_str ? enctype_str : "unknown enctype");
|
||||||
|
|
||||||
krb5_set_error_message(context, ret,
|
krb5_set_error_message(context, ret,
|
||||||
N_("Failed to find %s%s in keytab %s (%s)",
|
N_("Failed to find %s%s in keytab %s (%s)",
|
||||||
"principal, kvno, keytab file, enctype"),
|
"principal, kvno, keytab file, enctype"),
|
||||||
@@ -636,27 +675,81 @@ krb5_kt_get_entry_wrapped(krb5_context context,
|
|||||||
|
|
||||||
entry->vno = 0;
|
entry->vno = 0;
|
||||||
while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
|
while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
|
||||||
|
/* Always-log the entry we're inspecting and what is being requested */
|
||||||
|
{
|
||||||
|
char *entry_unp = NULL;
|
||||||
|
char *want_unp = NULL;
|
||||||
|
|
||||||
|
(void) krb5_unparse_name(context, tmp.principal, &entry_unp);
|
||||||
|
(void) krb5_unparse_name(context, principal, &want_unp);
|
||||||
|
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: inspecting entry=%s vno=%d enctype=%d against requested=%s kvno=%u enctype=%d",
|
||||||
|
entry_unp ? entry_unp : "<unparsed>",
|
||||||
|
tmp.vno,
|
||||||
|
tmp.keyblock.keytype,
|
||||||
|
want_unp ? want_unp : "<unparsed>",
|
||||||
|
(unsigned)kvno,
|
||||||
|
(int)enctype);
|
||||||
|
|
||||||
|
free(entry_unp);
|
||||||
|
free(want_unp);
|
||||||
|
}
|
||||||
|
|
||||||
if (krb5_kt_compare(context, &tmp, principal, 0, enctype)) {
|
if (krb5_kt_compare(context, &tmp, principal, 0, enctype)) {
|
||||||
/* the file keytab might only store the lower 8 bits of
|
/* the file keytab might only store the lower 8 bits of
|
||||||
the kvno, so only compare those bits */
|
the kvno, so only compare those bits */
|
||||||
if (kvno == tmp.vno
|
if (kvno == tmp.vno
|
||||||
|| (tmp.vno < 256 && kvno % 256 == tmp.vno)) {
|
|| (tmp.vno < 256 && kvno % 256 == tmp.vno)) {
|
||||||
|
/* Matched principal and kvno -> return this entry */
|
||||||
|
{
|
||||||
|
char *matched = NULL;
|
||||||
|
(void) krb5_unparse_name(context, tmp.principal, &matched);
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: matched entry=%s vno=%d enctype=%d -- returning",
|
||||||
|
matched ? matched : "<unparsed>",
|
||||||
|
tmp.vno,
|
||||||
|
tmp.keyblock.keytype);
|
||||||
|
free(matched);
|
||||||
|
}
|
||||||
krb5_kt_copy_entry_contents (context, &tmp, entry);
|
krb5_kt_copy_entry_contents (context, &tmp, entry);
|
||||||
krb5_kt_free_entry (context, &tmp);
|
krb5_kt_free_entry (context, &tmp);
|
||||||
krb5_kt_end_seq_get(context, id, &cursor);
|
krb5_kt_end_seq_get(context, id, &cursor);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (kvno == 0 && tmp.vno > entry->vno) {
|
} else if (kvno == 0 && tmp.vno > entry->vno) {
|
||||||
|
/* Matched principal but kvno selection logic prefers a higher vno */
|
||||||
|
{
|
||||||
|
char *matched = NULL;
|
||||||
|
(void) krb5_unparse_name(context, tmp.principal, &matched);
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: matched principal %s but kvno differs (entry.vno=%d tmp.vno=%d); selecting higher vno for now",
|
||||||
|
matched ? matched : "<unparsed>",
|
||||||
|
entry->vno,
|
||||||
|
tmp.vno);
|
||||||
|
free(matched);
|
||||||
|
}
|
||||||
if (entry->vno)
|
if (entry->vno)
|
||||||
krb5_kt_free_entry (context, entry);
|
krb5_kt_free_entry (context, entry);
|
||||||
krb5_kt_copy_entry_contents (context, &tmp, entry);
|
krb5_kt_copy_entry_contents (context, &tmp, entry);
|
||||||
|
} else {
|
||||||
|
/* Matched name but kvno didn't match and we are not in kvno-selection mode; log it. */
|
||||||
|
char *matched = NULL;
|
||||||
|
(void) krb5_unparse_name(context, tmp.principal, &matched);
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: matched principal %s but kvno mismatch (tmp.vno=%d requested_kvno=%u); continuing iteration",
|
||||||
|
matched ? matched : "<unparsed>",
|
||||||
|
tmp.vno,
|
||||||
|
(unsigned)kvno);
|
||||||
|
free(matched);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
krb5_kt_free_entry(context, &tmp);
|
krb5_kt_free_entry(context, &tmp);
|
||||||
}
|
}
|
||||||
krb5_kt_end_seq_get (context, id, &cursor);
|
krb5_kt_end_seq_get (context, id, &cursor);
|
||||||
if (entry->vno == 0)
|
if (entry->vno == 0) {
|
||||||
|
/* No matching kvno was found in the keytab iteration; log and return */
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: no matching entry found -> invoking _krb5_kt_principal_not_found");
|
||||||
return _krb5_kt_principal_not_found(context, KRB5_KT_NOTFOUND,
|
return _krb5_kt_principal_not_found(context, KRB5_KT_NOTFOUND,
|
||||||
id, principal, enctype, kvno);
|
id, principal, enctype, kvno);
|
||||||
|
}
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry_wrapped: returning selected entry vno=%d enctype=%d",
|
||||||
|
entry->vno, entry->keyblock.keytype);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,6 +781,25 @@ krb5_kt_get_entry(krb5_context context,
|
|||||||
krb5_const_principal try_princ;
|
krb5_const_principal try_princ;
|
||||||
krb5_name_canon_iterator name_canon_iter;
|
krb5_name_canon_iterator name_canon_iter;
|
||||||
|
|
||||||
|
/* Debug: record incoming keytab lookup request (always emitted) */
|
||||||
|
{
|
||||||
|
char *want_unp = NULL;
|
||||||
|
char *kt_full = NULL;
|
||||||
|
|
||||||
|
if (principal && krb5_unparse_name(context, principal, &want_unp) != 0)
|
||||||
|
want_unp = NULL;
|
||||||
|
(void) krb5_kt_get_full_name(context, id, &kt_full);
|
||||||
|
|
||||||
|
krb5_warnx(context, "krb5_kt_get_entry: requested principal=%s keytab=%s kvno=%u enctype=%d",
|
||||||
|
want_unp ? want_unp : "<null>",
|
||||||
|
kt_full ? kt_full : "<unknown>",
|
||||||
|
(unsigned)kvno,
|
||||||
|
(int)enctype);
|
||||||
|
|
||||||
|
free(want_unp);
|
||||||
|
free(kt_full);
|
||||||
|
}
|
||||||
|
|
||||||
if (!principal)
|
if (!principal)
|
||||||
/* Use `NULL' instead of `principal' to quiet static analizers */
|
/* Use `NULL' instead of `principal' to quiet static analizers */
|
||||||
return krb5_kt_get_entry_wrapped(context, id, NULL, kvno, enctype,
|
return krb5_kt_get_entry_wrapped(context, id, NULL, kvno, enctype,
|
||||||
|
|||||||
+61
-12
@@ -380,13 +380,21 @@ fkt_start_seq_get_int(krb5_context context,
|
|||||||
d->filename, strerror(ret));
|
d->filename, strerror(ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Loud logging: record that we opened the keytab file and process info */
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: opened keytab \"%s\" fd=%d flags=0x%x pid=%d uid=%d",
|
||||||
|
d->filename ? d->filename : "<null>",
|
||||||
|
c->fd,
|
||||||
|
(unsigned)flags,
|
||||||
|
(int)getpid(),
|
||||||
|
(int)getuid());
|
||||||
|
|
||||||
rk_cloexec(c->fd);
|
rk_cloexec(c->fd);
|
||||||
if (exclusive) {
|
ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
|
||||||
ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
|
if (ret) {
|
||||||
if (ret) {
|
krb5_warnx(context, "fkt_start_seq_get_int: failed to lock keytab \"%s\": ret=%d", d->filename ? d->filename : "<null>", ret);
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((flags & O_ACCMODE) == O_RDWR && (flags & O_APPEND))
|
if ((flags & O_ACCMODE) == O_RDWR && (flags & O_APPEND))
|
||||||
stdio_mode = "ab+";
|
stdio_mode = "ab+";
|
||||||
@@ -396,6 +404,7 @@ fkt_start_seq_get_int(krb5_context context,
|
|||||||
stdio_mode = "wb";
|
stdio_mode = "wb";
|
||||||
c->sp = krb5_storage_stdio_from_fd(c->fd, stdio_mode);
|
c->sp = krb5_storage_stdio_from_fd(c->fd, stdio_mode);
|
||||||
if (c->sp == NULL) {
|
if (c->sp == NULL) {
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: krb5_storage_stdio_from_fd returned NULL for \"%s\"", d->filename ? d->filename : "<null>");
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
return krb5_enomem(context);
|
return krb5_enomem(context);
|
||||||
}
|
}
|
||||||
@@ -405,12 +414,17 @@ fkt_start_seq_get_int(krb5_context context,
|
|||||||
krb5_storage_free(c->sp);
|
krb5_storage_free(c->sp);
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
krb5_clear_error_message(context);
|
krb5_clear_error_message(context);
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: failed reading pvno from \"%s\": ret=%d", d->filename ? d->filename : "<null>", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
/* Log the pvno read */
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: keytab \"%s\" pvno=%d", d->filename ? d->filename : "<null>", (int)pvno);
|
||||||
|
|
||||||
if(pvno != 5) {
|
if(pvno != 5) {
|
||||||
krb5_storage_free(c->sp);
|
krb5_storage_free(c->sp);
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
krb5_clear_error_message (context);
|
krb5_clear_error_message (context);
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: keytab \"%s\" has bad vno (%d)", d->filename ? d->filename : "<null>", (int)pvno);
|
||||||
return KRB5_KEYTAB_BADVNO;
|
return KRB5_KEYTAB_BADVNO;
|
||||||
}
|
}
|
||||||
ret = krb5_ret_int8(c->sp, &tag);
|
ret = krb5_ret_int8(c->sp, &tag);
|
||||||
@@ -418,10 +432,19 @@ fkt_start_seq_get_int(krb5_context context,
|
|||||||
krb5_storage_free(c->sp);
|
krb5_storage_free(c->sp);
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
krb5_clear_error_message(context);
|
krb5_clear_error_message(context);
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: failed reading tag from \"%s\": ret=%d", d->filename ? d->filename : "<null>", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Log the tag/version we read */
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: keytab \"%s\" header tag=%d", d->filename ? d->filename : "<null>", (int)tag);
|
||||||
|
|
||||||
id->version = tag;
|
id->version = tag;
|
||||||
storage_set_flags(context, c->sp, id->version);
|
storage_set_flags(context, c->sp, id->version);
|
||||||
|
|
||||||
|
/* Final confirmation log */
|
||||||
|
krb5_warnx(context, "fkt_start_seq_get_int: keytab \"%s\" opened successfully (fd=%d, version=%d)", d->filename ? d->filename : "<null>", c->fd, (int)id->version);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,26 +475,50 @@ fkt_next_entry_int(krb5_context context,
|
|||||||
pos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
|
pos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
|
||||||
loop:
|
loop:
|
||||||
ret = krb5_ret_int32(cursor->sp, &len);
|
ret = krb5_ret_int32(cursor->sp, &len);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: krb5_ret_int32 returned %d for keytab \"%s\" at pos=%lld", ret, d->filename ? d->filename : "<null>", (long long)pos);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
if(len < 0) {
|
if(len < 0) {
|
||||||
pos = krb5_storage_seek(cursor->sp, -len, SEEK_CUR);
|
pos = krb5_storage_seek(cursor->sp, -len, SEEK_CUR);
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
ret = krb5_kt_ret_principal (context, d, cursor->sp, &entry->principal);
|
ret = krb5_kt_ret_principal (context, d, cursor->sp, &entry->principal);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: krb5_kt_ret_principal failed for keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
ret = krb5_ret_uint32(cursor->sp, &utmp32);
|
ret = krb5_ret_uint32(cursor->sp, &utmp32);
|
||||||
entry->timestamp = utmp32;
|
entry->timestamp = utmp32;
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: failed reading timestamp for keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
ret = krb5_ret_int8(cursor->sp, &tmp8);
|
ret = krb5_ret_int8(cursor->sp, &tmp8);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: failed reading vno (8bit) for keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
entry->vno = tmp8;
|
entry->vno = tmp8;
|
||||||
ret = krb5_kt_ret_keyblock (context, d, cursor->sp, &entry->keyblock);
|
ret = krb5_kt_ret_keyblock (context, d, cursor->sp, &entry->keyblock);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: krb5_kt_ret_keyblock failed for keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Log the entry we just read (principal, vno, enctype, timestamp) */
|
||||||
|
{
|
||||||
|
char *princname = NULL;
|
||||||
|
(void) krb5_unparse_name(context, entry->principal, &princname);
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: read entry principal=%s pos=%lld timestamp=%u vno=%d enctype=%d",
|
||||||
|
princname ? princname : "<unparsed>",
|
||||||
|
(long long)pos,
|
||||||
|
(unsigned)entry->timestamp,
|
||||||
|
entry->vno,
|
||||||
|
entry->keyblock.keytype);
|
||||||
|
free(princname);
|
||||||
|
}
|
||||||
|
|
||||||
/* there might be a 32 bit kvno here
|
/* there might be a 32 bit kvno here
|
||||||
* if it's zero, assume that the 8bit one was right,
|
* if it's zero, assume that the 8bit one was right,
|
||||||
* otherwise trust the new value */
|
* otherwise trust the new value */
|
||||||
@@ -494,8 +541,10 @@ loop:
|
|||||||
if(start) *start = pos;
|
if(start) *start = pos;
|
||||||
if(end) *end = pos + 4 + len;
|
if(end) *end = pos + 4 + len;
|
||||||
out:
|
out:
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_warnx(context, "fkt_next_entry_int: error reading keytab \"%s\" at pos=%lld: ret=%d", d->filename ? d->filename : "<null>", (long long)pos, ret);
|
||||||
krb5_kt_free_entry(context, entry);
|
krb5_kt_free_entry(context, entry);
|
||||||
|
}
|
||||||
krb5_storage_seek(cursor->sp, pos + 4 + len, SEEK_SET);
|
krb5_storage_seek(cursor->sp, pos + 4 + len, SEEK_SET);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
.Dt KRB5_CONTEXT 3
|
.Dt KRB5_CONTEXT 3
|
||||||
.Os HEIMDAL
|
.Os HEIMDAL
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
.Nm krb5_add_et_list ,
|
||||||
.Nm krb5_add_extra_addresses ,
|
.Nm krb5_add_extra_addresses ,
|
||||||
.Nm krb5_add_ignore_addresses ,
|
.Nm krb5_add_ignore_addresses ,
|
||||||
.Nm krb5_context ,
|
.Nm krb5_context ,
|
||||||
@@ -47,7 +48,7 @@
|
|||||||
.Nm krb5_get_ignore_addresses ,
|
.Nm krb5_get_ignore_addresses ,
|
||||||
.Nm krb5_get_kdc_sec_offset ,
|
.Nm krb5_get_kdc_sec_offset ,
|
||||||
.Nm krb5_get_max_time_skew ,
|
.Nm krb5_get_max_time_skew ,
|
||||||
.Nm krb5_get_use_admin_kdc ,
|
.Nm krb5_get_use_admin_kdc
|
||||||
.Nm krb5_init_context ,
|
.Nm krb5_init_context ,
|
||||||
.Nm krb5_init_ets ,
|
.Nm krb5_init_ets ,
|
||||||
.Nm krb5_prepend_config_files ,
|
.Nm krb5_prepend_config_files ,
|
||||||
@@ -58,7 +59,7 @@
|
|||||||
.Nm krb5_set_fcache_version ,
|
.Nm krb5_set_fcache_version ,
|
||||||
.Nm krb5_set_ignore_addresses ,
|
.Nm krb5_set_ignore_addresses ,
|
||||||
.Nm krb5_set_max_time_skew ,
|
.Nm krb5_set_max_time_skew ,
|
||||||
.Nm krb5_set_use_admin_kdc
|
.Nm krb5_set_use_admin_kdc ,
|
||||||
.Nd create, modify and delete krb5_context structures
|
.Nd create, modify and delete krb5_context structures
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
Kerberos 5 Library (libkrb5, -lkrb5)
|
Kerberos 5 Library (libkrb5, -lkrb5)
|
||||||
@@ -80,6 +81,11 @@ Kerberos 5 Library (libkrb5, -lkrb5)
|
|||||||
.Fa "krb5_context context"
|
.Fa "krb5_context context"
|
||||||
.Fc
|
.Fc
|
||||||
.Ft krb5_error_code
|
.Ft krb5_error_code
|
||||||
|
.Fo krb5_add_et_list
|
||||||
|
.Fa "krb5_context context"
|
||||||
|
.Fa "void (*func)(struct et_list **)"
|
||||||
|
.Fc
|
||||||
|
.Ft krb5_error_code
|
||||||
.Fo krb5_add_extra_addresses
|
.Fo krb5_add_extra_addresses
|
||||||
.Fa "krb5_context context"
|
.Fa "krb5_context context"
|
||||||
.Fa "krb5_addresses *addresses"
|
.Fa "krb5_addresses *addresses"
|
||||||
@@ -198,11 +204,23 @@ or that Kerberos should not be used
|
|||||||
.Bq ENXIO .
|
.Bq ENXIO .
|
||||||
.Pp
|
.Pp
|
||||||
.Fn krb5_init_ets
|
.Fn krb5_init_ets
|
||||||
is retained for ABI compatibility.
|
adds all
|
||||||
It does not perform any action.
|
.Xr com_err 3
|
||||||
Any initialization it used to provide is done by
|
libs to
|
||||||
|
.Fa context .
|
||||||
|
This is done by
|
||||||
.Fn krb5_init_context .
|
.Fn krb5_init_context .
|
||||||
.Pp
|
.Pp
|
||||||
|
.Fn krb5_add_et_list
|
||||||
|
adds a
|
||||||
|
.Xr com_err 3
|
||||||
|
error-code handler
|
||||||
|
.Fa func
|
||||||
|
to the specified
|
||||||
|
.Fa context .
|
||||||
|
The error handler must generated by the the re-rentrant version of the
|
||||||
|
.Xr compile_et 1
|
||||||
|
program.
|
||||||
.Fn krb5_add_extra_addresses
|
.Fn krb5_add_extra_addresses
|
||||||
add a list of addresses that should be added when requesting tickets.
|
add a list of addresses that should be added when requesting tickets.
|
||||||
.Pp
|
.Pp
|
||||||
@@ -284,5 +302,7 @@ and
|
|||||||
get and sets the maximum allowed time skew between client and server.
|
get and sets the maximum allowed time skew between client and server.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr errno 2 ,
|
.Xr errno 2 ,
|
||||||
.Xr krb5.conf 5 ,
|
.Xr krb5 3 ,
|
||||||
|
.Xr krb5_config 3 ,
|
||||||
|
.Xr krb5_context 3 ,
|
||||||
.Xr kerberos 8
|
.Xr kerberos 8
|
||||||
|
|||||||
@@ -91,13 +91,11 @@ cleans the the structure, must be used before trying to pass it in to
|
|||||||
.Fn krb5_verify_init_creds .
|
.Fn krb5_verify_init_creds .
|
||||||
.Pp
|
.Pp
|
||||||
.Fn krb5_verify_init_creds_opt_set_ap_req_nofail
|
.Fn krb5_verify_init_creds_opt_set_ap_req_nofail
|
||||||
controls the behavior if
|
controls controls the behavior if
|
||||||
.Fa ap_req_server
|
.Fa ap_req_server
|
||||||
does not exist in the local keytab or in the KDC's database.
|
doesn't exists in the local keytab or in the KDC's database, if it's
|
||||||
If it is true, those errors will not be ignored.
|
true, the error will be ignored. Note that this use is possible
|
||||||
Errors from AP_REQ verification with a present key, such as an integrity
|
insecure.
|
||||||
check failure, are always returned.
|
|
||||||
Note that ignoring the error is possibly insecure.
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr krb5 3 ,
|
.Xr krb5 3 ,
|
||||||
.Xr krb5_get_init_creds 3 ,
|
.Xr krb5_get_init_creds 3 ,
|
||||||
|
|||||||
@@ -231,6 +231,11 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
.Ed
|
.Ed
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
|
.Xr krb5_cc_gen_new 3 ,
|
||||||
|
.Xr krb5_cc_initialize 3 ,
|
||||||
|
.Xr krb5_cc_resolve 3 ,
|
||||||
|
.Xr krb5_err 3 ,
|
||||||
.Xr krb5_free_principal 3 ,
|
.Xr krb5_free_principal 3 ,
|
||||||
.Xr krb5_init_context 3 ,
|
.Xr krb5_init_context 3 ,
|
||||||
|
.Xr krb5_kt_default 3 ,
|
||||||
.Xr krb5.conf 5
|
.Xr krb5.conf 5
|
||||||
|
|||||||
+19
-25
@@ -1193,35 +1193,29 @@ 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)
|
||||||
|
return KRB5_CC_END;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're pointing at the entry with the principal, or at the key
|
||||||
|
* with the time offsets, skip it.
|
||||||
|
*/
|
||||||
|
while (krcursor->keys[krcursor->currkey] == krcursor->princ_id ||
|
||||||
|
krcursor->keys[krcursor->currkey] == krcursor->offsets_id) {
|
||||||
|
krcursor->currkey++;
|
||||||
if (krcursor->currkey >= krcursor->numkeys)
|
if (krcursor->currkey >= krcursor->numkeys)
|
||||||
return KRB5_CC_END;
|
return KRB5_CC_END;
|
||||||
|
|
||||||
/*
|
|
||||||
* If we're pointing at the entry with the principal, or at the key
|
|
||||||
* with the time offsets, skip it.
|
|
||||||
*/
|
|
||||||
while (krcursor->keys[krcursor->currkey] == krcursor->princ_id ||
|
|
||||||
krcursor->keys[krcursor->currkey] == krcursor->offsets_id) {
|
|
||||||
krcursor->currkey++;
|
|
||||||
if (krcursor->currkey >= krcursor->numkeys)
|
|
||||||
return KRB5_CC_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = keyctl_read_krb5_data(krcursor->keys[krcursor->currkey],
|
|
||||||
&payload);
|
|
||||||
krcursor->currkey++;
|
|
||||||
if (ret == KRB5_FCC_NOFILE)
|
|
||||||
continue;
|
|
||||||
if (ret) {
|
|
||||||
_krb5_debug(context, 10, "Error reading key %d: %s\n",
|
|
||||||
krcursor->keys[krcursor->currkey - 1],
|
|
||||||
strerror(errno));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = keyctl_read_krb5_data(krcursor->keys[krcursor->currkey], &payload);
|
||||||
|
if (ret) {
|
||||||
|
_krb5_debug(context, 10, "Error reading key %d: %s\n",
|
||||||
|
krcursor->keys[krcursor->currkey],
|
||||||
|
strerror(errno));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
krcursor->currkey++;
|
||||||
|
|
||||||
sp = krb5_storage_from_data(&payload);
|
sp = krb5_storage_from_data(&payload);
|
||||||
if (sp == NULL) {
|
if (sp == NULL) {
|
||||||
ret = KRB5_CC_IO;
|
ret = KRB5_CC_IO;
|
||||||
|
|||||||
+54
-36
@@ -1466,18 +1466,23 @@ krb5_sname_to_principal(krb5_context context,
|
|||||||
for (cp = remote_host; *cp; cp++)
|
for (cp = remote_host; *cp; cp++)
|
||||||
if (isupper((unsigned char) (*cp)))
|
if (isupper((unsigned char) (*cp)))
|
||||||
*cp = tolower((unsigned char) (*cp));
|
*cp = tolower((unsigned char) (*cp));
|
||||||
|
/* Debug-ish: record the input/normalized hostname and service for tracing. */
|
||||||
|
krb5_warnx(context, "krb5_sname_to_principal: remote_host=%s sname=%s type=%d",
|
||||||
|
remote_host ? remote_host : "<null>",
|
||||||
|
sname ? sname : "<null>",
|
||||||
|
(int)type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is only one name canon rule and it says to
|
* If there is only one name canon rule and it says to
|
||||||
* canonicalize the old way, do that now, as we used to.
|
* canonicalize the old way, do that now, as we used to.
|
||||||
*/
|
*/
|
||||||
ret = _krb5_get_name_canon_rules(context, &rules);
|
ret = _krb5_get_name_canon_rules(context, &rules);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
_krb5_debug(context, 5, "Failed to get name canon rules: ret = %d",
|
krb5_warnx(context, "Failed to get name canon rules: ret = %d",
|
||||||
ret);
|
ret);
|
||||||
free(remote_host);
|
free(remote_host);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (rules[0].type == KRB5_NCRT_NSS &&
|
if (rules[0].type == KRB5_NCRT_NSS &&
|
||||||
rules[1].type == KRB5_NCRT_BOGUS) {
|
rules[1].type == KRB5_NCRT_BOGUS) {
|
||||||
_krb5_debug(context, 5, "Using nss for name canon immediately");
|
_krb5_debug(context, 5, "Using nss for name canon immediately");
|
||||||
@@ -1895,6 +1900,17 @@ apply_name_canon_rule(krb5_context context, krb5_name_canon_rule rules,
|
|||||||
|
|
||||||
_krb5_debug(context, 5, N_("Applying a name rule (type %d) to %s", ""),
|
_krb5_debug(context, 5, N_("Applying a name rule (type %d) to %s", ""),
|
||||||
rule->type, orig_hostname);
|
rule->type, orig_hostname);
|
||||||
|
/* Extra debug: print rule details to help trace name canonicalization. */
|
||||||
|
krb5_warnx(context, "name_canon: rule_idx=%zu type=%d mindots=%u maxdots=%u match_domain=%s match_realm=%s realm=%s domain=%s options=0x%x",
|
||||||
|
rule_idx,
|
||||||
|
(int)rule->type,
|
||||||
|
(unsigned)rule->mindots,
|
||||||
|
(unsigned)rule->maxdots,
|
||||||
|
rule->match_domain ? rule->match_domain : "<null>",
|
||||||
|
rule->match_realm ? rule->match_realm : "<null>",
|
||||||
|
rule->realm ? rule->realm : "<null>",
|
||||||
|
rule->domain ? rule->domain : "<null>",
|
||||||
|
(int)rule->options);
|
||||||
|
|
||||||
if (rule->mindots > 0 || rule->maxdots > 0) {
|
if (rule->mindots > 0 || rule->maxdots > 0) {
|
||||||
for (cp = strchr(orig_hostname, '.'); cp && *cp; cp = strchr(cp + 1, '.'))
|
for (cp = strchr(orig_hostname, '.'); cp && *cp; cp = strchr(cp + 1, '.'))
|
||||||
@@ -1929,36 +1945,38 @@ apply_name_canon_rule(krb5_context context, krb5_name_canon_rule rules,
|
|||||||
new_hostname = tmp_hostname;
|
new_hostname = tmp_hostname;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KRB5_NCRT_NSS:
|
case KRB5_NCRT_NSS:
|
||||||
if ((rule->options & KRB5_NCRO_USE_DNSSEC)) {
|
if ((rule->options & KRB5_NCRO_USE_DNSSEC)) {
|
||||||
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
|
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
|
||||||
krb5_set_error_message(context, ret,
|
krb5_set_error_message(context, ret,
|
||||||
"Secure hostname resolution not supported");
|
"Secure hostname resolution not supported");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
_krb5_debug(context, 5, "Using name service lookups");
|
_krb5_debug(context, 5, "Using name service lookups");
|
||||||
ret = krb5_sname_to_principal_old(context, rule->realm,
|
ret = krb5_sname_to_principal_old(context, rule->realm,
|
||||||
orig_hostname, sname,
|
orig_hostname, sname,
|
||||||
KRB5_NT_SRV_HST,
|
KRB5_NT_SRV_HST,
|
||||||
&nss);
|
&nss);
|
||||||
if (rules[rule_idx + 1].type != KRB5_NCRT_BOGUS &&
|
/* If subsequent rule exists and we got a hostname/realm error,
|
||||||
(ret == KRB5_ERR_BAD_HOSTNAME ||
|
* treat this rule as inapplicable (unless last rule). */
|
||||||
ret == KRB5_ERR_HOST_REALM_UNKNOWN)) {
|
if (rules[rule_idx + 1].type != KRB5_NCRT_BOGUS &&
|
||||||
/*
|
(ret == KRB5_ERR_BAD_HOSTNAME ||
|
||||||
* Bad hostname / realm unknown -> rule inapplicable if
|
ret == KRB5_ERR_HOST_REALM_UNKNOWN)) {
|
||||||
* there's more rules. If it's the last rule then we want
|
ret = 0;
|
||||||
* to return all errors from krb5_sname_to_principal_old()
|
goto out;
|
||||||
* here.
|
}
|
||||||
*/
|
if (ret) {
|
||||||
ret = 0;
|
_krb5_debug(context, 3, "krb5_sname_to_principal_old failed for %s: ret=%d", orig_hostname, ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
new_hostname = krb5_principal_get_comp_string(context, nss, 1);
|
new_hostname = krb5_principal_get_comp_string(context, nss, 1);
|
||||||
new_realm = krb5_principal_get_realm(context, nss);
|
new_realm = krb5_principal_get_realm(context, nss);
|
||||||
break;
|
/* Log what nss resolution produced for inspection in tests */
|
||||||
|
_krb5_debug(context, 3, "krb5_sname_to_principal_old: resolved %s -> canonical=%s realm=%s", orig_hostname,
|
||||||
|
new_hostname ? new_hostname : "<null>",
|
||||||
|
new_realm ? new_realm : "<null>");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Can't happen */
|
/* Can't happen */
|
||||||
|
|||||||
+53
-69
@@ -1084,6 +1084,13 @@ 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);
|
||||||
@@ -1155,11 +1162,9 @@ 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;
|
||||||
struct pollfd *pfds;
|
fd_set wfds;
|
||||||
struct host **hosts;
|
rk_socket_t max_fd;
|
||||||
nfds_t nfds;
|
|
||||||
|
|
||||||
int got_reply;
|
int got_reply;
|
||||||
time_t timenow;
|
time_t timenow;
|
||||||
};
|
};
|
||||||
@@ -1170,8 +1175,6 @@ 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;
|
||||||
@@ -1195,32 +1198,31 @@ wait_setup(heim_object_t obj, void *iter_ctx, int *stop)
|
|||||||
host_connected(wait_ctx->context, wait_ctx->ctx, h);
|
host_connected(wait_ctx->context, wait_ctx->ctx, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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:
|
||||||
events |= POLLIN;
|
FD_SET(h->fd, &wait_ctx->rfds);
|
||||||
break;
|
break;
|
||||||
case CONNECTING:
|
case CONNECTING:
|
||||||
case CONNECTED:
|
case CONNECTED:
|
||||||
events |= POLLIN | POLLOUT;
|
FD_SET(h->fd, &wait_ctx->rfds);
|
||||||
|
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))
|
||||||
events |= POLLIN;
|
FD_SET(h->fd, &wait_ctx->rfds);
|
||||||
if (_krb5_socks4a_writing(h->socks4a))
|
if (_krb5_socks4a_writing(h->socks4a))
|
||||||
events |= POLLOUT;
|
FD_SET(h->fd, &wait_ctx->wfds);
|
||||||
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->pfds[wait_ctx->nfds].fd = h->fd;
|
wait_ctx->max_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
|
||||||
@@ -1240,39 +1242,39 @@ wait_accelerate(heim_object_t obj, void *ctx, int *stop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wait_process(struct wait_ctx *wait_ctx)
|
wait_process(heim_object_t obj, void *ctx, int *stop)
|
||||||
{
|
{
|
||||||
for (nfds_t i = 0; i < wait_ctx->nfds; i++) {
|
struct wait_ctx *wait_ctx = ctx;
|
||||||
struct host *h = wait_ctx->hosts[i];
|
struct host *h = (struct host *)obj;
|
||||||
struct pollfd *pfd = &wait_ctx->pfds[i];
|
int readable, writeable;
|
||||||
|
heim_assert(h->state != DEAD, "dead host resurected");
|
||||||
|
|
||||||
int readable = pfd->revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL);
|
#ifndef NO_LIMIT_FD_SETSIZE
|
||||||
int writeable = pfd->revents & POLLOUT;
|
heim_assert(h->fd < FD_SETSIZE, "fd too large");
|
||||||
|
#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->got_reply |= eval_host_state(wait_ctx->context, wait_ctx->ctx, h, readable, writeable);
|
||||||
wait_ctx->context,
|
|
||||||
wait_ctx->ctx,
|
|
||||||
h,
|
|
||||||
readable,
|
|
||||||
writeable
|
|
||||||
);
|
|
||||||
|
|
||||||
if (wait_ctx->got_reply)
|
/* if there is already a reply, just fall though the array */
|
||||||
return;
|
if (wait_ctx->got_reply)
|
||||||
}
|
*stop = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@@ -1282,8 +1284,10 @@ wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
|
|||||||
|
|
||||||
wait_ctx.timenow = time(NULL);
|
wait_ctx.timenow = time(NULL);
|
||||||
|
|
||||||
size_t max_hosts = heim_array_get_length(ctx->hosts);
|
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_setup);
|
||||||
if (max_hosts == 0) {
|
heim_array_filter_f(ctx->hosts, &wait_ctx, wait_filter_dead);
|
||||||
|
|
||||||
|
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");
|
||||||
@@ -1296,18 +1300,7 @@ wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_ctx.pfds = calloc(max_hosts, sizeof(struct pollfd));
|
if (wait_ctx.max_fd == rk_INVALID_SOCKET) {
|
||||||
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
|
||||||
@@ -1315,36 +1308,27 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = poll(wait_ctx.pfds, wait_ctx.nfds, 1000); /* 1s */
|
tv.tv_sec = 1;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
if (ret < 0) {
|
ret = select(wait_ctx.max_fd + 1, &wait_ctx.rfds, &wait_ctx.wfds, NULL, &tv);
|
||||||
free(wait_ctx.pfds);
|
if (ret < 0)
|
||||||
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);
|
return 0;
|
||||||
free(wait_ctx.hosts);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_ctx.got_reply = 0;
|
wait_ctx.got_reply = 0;
|
||||||
wait_process(&wait_ctx);
|
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_process);
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2294
File diff suppressed because it is too large
Load Diff
@@ -239,47 +239,10 @@ 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,8 +10,3 @@
|
|||||||
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
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user